| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #import "chrome/browser/ui/cocoa/full_size_content_window.h" | 5 #import "chrome/browser/ui/cocoa/full_size_content_window.h" |
| 6 | 6 |
| 7 #include <crt_externs.h> |
| 8 |
| 9 #include "base/auto_reset.h" |
| 7 #include "base/logging.h" | 10 #include "base/logging.h" |
| 8 #include "base/mac/foundation_util.h" | 11 #include "base/mac/foundation_util.h" |
| 12 #include "base/mac/scoped_objc_class_swizzler.h" |
| 9 | 13 |
| 10 @interface FullSizeContentWindow () | 14 @interface FullSizeContentWindow () |
| 11 | 15 |
| 12 + (BOOL)shouldUseFullSizeContentViewForStyle:(NSUInteger)windowStyle; | 16 + (BOOL)shouldUseFullSizeContentViewForStyle:(NSUInteger)windowStyle; |
| 13 | 17 |
| 14 @end | 18 @end |
| 15 | 19 |
| 16 // This view always takes the size of its superview. It is intended to be used | 20 // This view always takes the size of its superview. It is intended to be used |
| 17 // as a NSWindow's contentView. It is needed because NSWindow's implementation | 21 // as a NSWindow's contentView. It is needed because NSWindow's implementation |
| 18 // explicitly resizes the contentView at inopportune times. | 22 // explicitly resizes the contentView at inopportune times. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 37 } | 41 } |
| 38 | 42 |
| 39 - (void)forceFrame:(NSRect)frame { | 43 - (void)forceFrame:(NSRect)frame { |
| 40 forceFrameFlag_ = YES; | 44 forceFrameFlag_ = YES; |
| 41 [super setFrame:frame]; | 45 [super setFrame:frame]; |
| 42 forceFrameFlag_ = NO; | 46 forceFrameFlag_ = NO; |
| 43 } | 47 } |
| 44 | 48 |
| 45 @end | 49 @end |
| 46 | 50 |
| 51 static bool g_disable_callstacksymbols = false; |
| 52 static IMP g_original_callstacksymbols_implementation; |
| 53 |
| 54 @interface FullSizeContentWindowSwizzlingSupport : NSObject |
| 55 @end |
| 56 |
| 57 @implementation FullSizeContentWindowSwizzlingSupport |
| 58 |
| 59 // This method replaces [NSThread callStackSymbols] via swizzling - see +load |
| 60 // below. |
| 61 + (NSArray*)callStackSymbols { |
| 62 return g_disable_callstacksymbols ? |
| 63 @[@"+callStackSymbols disabled for performance reasons"] : |
| 64 g_original_callstacksymbols_implementation( |
| 65 self, @selector(callStackSymbols)); |
| 66 } |
| 67 |
| 68 @end |
| 69 |
| 47 @implementation FullSizeContentWindow | 70 @implementation FullSizeContentWindow |
| 48 | 71 |
| 49 #pragma mark - Lifecycle | 72 #pragma mark - Lifecycle |
| 50 | 73 |
| 74 // In initWithContentRect:styleMask:backing:defer:, the call to |
| 75 // [NSView addSubview:positioned:relativeTo:] causes NSWindow to complain that |
| 76 // an unknown view is being added to it, and to generate a stack trace. |
| 77 // Not only does this stack trace pollute the console, it can also take hundreds |
| 78 // of milliseconds to generate (because of symbolication). By swizzling |
| 79 // [NSThread callStackSymbols] we can prevent the stack trace output. |
| 80 // See crbug.com/520373 . |
| 81 + (void)load { |
| 82 // Swizzling should only happen in the browser process. |
| 83 const char* const* const argv = *_NSGetArgv(); |
| 84 const int argc = *_NSGetArgc(); |
| 85 const char kType[] = "--type="; |
| 86 for (int i = 1; i < argc; ++i) { |
| 87 const char* arg = argv[i]; |
| 88 if (strncmp(arg, kType, strlen(kType)) == 0) { |
| 89 return; |
| 90 } |
| 91 } |
| 92 |
| 93 static dispatch_once_t onceToken; |
| 94 dispatch_once(&onceToken, ^{ |
| 95 Class targetClass = [NSThread class]; |
| 96 Class swizzleClass = [FullSizeContentWindowSwizzlingSupport class]; |
| 97 SEL targetSelector = @selector(callStackSymbols); |
| 98 |
| 99 CR_DEFINE_STATIC_LOCAL(base::mac::ScopedObjCClassSwizzler, |
| 100 callStackSymbolsSuppressor, (targetClass, |
| 101 swizzleClass, targetSelector)); |
| 102 g_original_callstacksymbols_implementation = |
| 103 callStackSymbolsSuppressor.GetOriginalImplementation(); |
| 104 }); |
| 105 } |
| 106 |
| 51 - (instancetype)init { | 107 - (instancetype)init { |
| 52 NOTREACHED(); | 108 NOTREACHED(); |
| 53 return nil; | 109 return nil; |
| 54 } | 110 } |
| 55 | 111 |
| 56 - (instancetype)initWithContentRect:(NSRect)contentRect | 112 - (instancetype)initWithContentRect:(NSRect)contentRect |
| 57 styleMask:(NSUInteger)windowStyle | 113 styleMask:(NSUInteger)windowStyle |
| 58 backing:(NSBackingStoreType)bufferingType | 114 backing:(NSBackingStoreType)bufferingType |
| 59 defer:(BOOL)deferCreation { | 115 defer:(BOOL)deferCreation { |
| 60 return [self initWithContentRect:contentRect | 116 return [self initWithContentRect:contentRect |
| (...skipping 19 matching lines...) Expand all Loading... |
| 80 chromeWindowView_.reset([[FullSizeContentView alloc] init]); | 136 chromeWindowView_.reset([[FullSizeContentView alloc] init]); |
| 81 [chromeWindowView_ | 137 [chromeWindowView_ |
| 82 setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; | 138 setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; |
| 83 [self setContentView:chromeWindowView_]; | 139 [self setContentView:chromeWindowView_]; |
| 84 [chromeWindowView_ setFrame:[[chromeWindowView_ superview] bounds]]; | 140 [chromeWindowView_ setFrame:[[chromeWindowView_ superview] bounds]]; |
| 85 | 141 |
| 86 // Our content view overlaps the window control buttons, so we must ensure | 142 // Our content view overlaps the window control buttons, so we must ensure |
| 87 // it is positioned below the buttons. | 143 // it is positioned below the buttons. |
| 88 NSView* superview = [chromeWindowView_ superview]; | 144 NSView* superview = [chromeWindowView_ superview]; |
| 89 [chromeWindowView_ removeFromSuperview]; | 145 [chromeWindowView_ removeFromSuperview]; |
| 146 |
| 147 // Prevent the AppKit from generating a backtrace to include in it's |
| 148 // complaint about our upcoming call to addSubview:positioned:relativeTo:. |
| 149 // See +load for more info. |
| 150 base::AutoReset<bool> disable_symbolication(&g_disable_callstacksymbols, |
| 151 true); |
| 152 |
| 90 [superview addSubview:chromeWindowView_ | 153 [superview addSubview:chromeWindowView_ |
| 91 positioned:NSWindowBelow | 154 positioned:NSWindowBelow |
| 92 relativeTo:nil]; | 155 relativeTo:nil]; |
| 93 } | 156 } |
| 94 } | 157 } |
| 95 return self; | 158 return self; |
| 96 } | 159 } |
| 97 | 160 |
| 98 - (void)forceContentViewFrame:(NSRect)frame { | 161 - (void)forceContentViewFrame:(NSRect)frame { |
| 99 FullSizeContentView* contentView = | 162 FullSizeContentView* contentView = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 127 return [super contentRectForFrameRect:fRect styleMask:aStyle]; | 190 return [super contentRectForFrameRect:fRect styleMask:aStyle]; |
| 128 } | 191 } |
| 129 | 192 |
| 130 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { | 193 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { |
| 131 if (chromeWindowView_) | 194 if (chromeWindowView_) |
| 132 return frameRect; | 195 return frameRect; |
| 133 return [super contentRectForFrameRect:frameRect]; | 196 return [super contentRectForFrameRect:frameRect]; |
| 134 } | 197 } |
| 135 | 198 |
| 136 @end | 199 @end |
| OLD | NEW |