| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser_frame_view.h" | 5 #import "chrome/browser/ui/cocoa/browser_frame_view.h" |
| 6 | 6 |
| 7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
| 8 #import <Carbon/Carbon.h> | 8 #import <Carbon/Carbon.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
| 12 #include "base/mac/scoped_nsautorelease_pool.h" | 12 #include "base/mac/scoped_nsautorelease_pool.h" |
| 13 #import "chrome/browser/themes/theme_service.h" | 13 #import "chrome/browser/themes/theme_service.h" |
| 14 #import "chrome/browser/ui/cocoa/framed_browser_window.h" | 14 #import "chrome/browser/ui/cocoa/framed_browser_window.h" |
| 15 #import "chrome/browser/ui/cocoa/themed_window.h" | 15 #import "chrome/browser/ui/cocoa/themed_window.h" |
| 16 #include "grit/theme_resources.h" | 16 #include "grit/theme_resources.h" |
| 17 #include "grit/theme_resources_standard.h" | 17 #include "grit/theme_resources_standard.h" |
| 18 | 18 |
| 19 static const CGFloat kBrowserFrameViewPaintHeight = 60.0; | 19 static const CGFloat kBrowserFrameViewPaintHeight = 60.0; |
| 20 static const NSPoint kBrowserFrameViewPatternPhaseOffset = { -5, 3 }; | 20 static const NSPoint kBrowserFrameViewPatternPhaseOffset = { -5, 3 }; |
| 21 | 21 |
| 22 static BOOL gCanDrawTitle = NO; | 22 static BOOL gCanDrawTitle = NO; |
| 23 static BOOL gCanGetCornerRadius = NO; | 23 static BOOL gCanGetCornerRadius = NO; |
| 24 | 24 |
| 25 @interface NSView (Swizzles) | 25 @interface NSView (Swizzles) |
| 26 - (void)drawRectOriginal:(NSRect)rect; | 26 - (void)drawRectOriginal:(NSRect)rect; |
| 27 - (NSUInteger)_shadowFlagsOriginal; | |
| 28 @end | 27 @end |
| 29 | 28 |
| 30 // Undocumented APIs. They are really on NSGrayFrame rather than | 29 // Undocumented APIs. They are really on NSGrayFrame rather than |
| 31 // BrowserFrameView, but we call them from methods swizzled onto NSGrayFrame. | 30 // BrowserFrameView, but we call them from methods swizzled onto NSGrayFrame. |
| 32 @interface BrowserFrameView (UndocumentedAPI) | 31 @interface BrowserFrameView (UndocumentedAPI) |
| 33 | 32 |
| 34 - (float)roundedCornerRadius; | 33 - (float)roundedCornerRadius; |
| 35 - (CGRect)_titlebarTitleRect; | 34 - (CGRect)_titlebarTitleRect; |
| 36 - (void)_drawTitleStringIn:(struct CGRect)arg1 withColor:(id)color; | 35 - (void)_drawTitleStringIn:(struct CGRect)arg1 withColor:(id)color; |
| 37 - (NSUInteger)_shadowFlags; | |
| 38 | 36 |
| 39 @end | 37 @end |
| 40 | 38 |
| 41 @implementation BrowserFrameView | 39 @implementation BrowserFrameView |
| 42 | 40 |
| 43 + (void)load { | 41 + (void)load { |
| 44 // This is where we swizzle drawRect, and add in two methods that we | 42 // This is where we swizzle drawRect, and add in two methods that we |
| 45 // need. If any of these fail it shouldn't affect the functionality of the | 43 // need. If any of these fail it shouldn't affect the functionality of the |
| 46 // others. If they all fail, we will lose window frame theming and | 44 // others. If they all fail, we will lose window frame theming and |
| 47 // roll overs for our close widgets, but things should still function | 45 // roll overs for our close widgets, but things should still function |
| (...skipping 29 matching lines...) Expand all Loading... |
| 77 } | 75 } |
| 78 | 76 |
| 79 gCanDrawTitle = | 77 gCanDrawTitle = |
| 80 [borderViewClass | 78 [borderViewClass |
| 81 instancesRespondToSelector:@selector(_titlebarTitleRect)] && | 79 instancesRespondToSelector:@selector(_titlebarTitleRect)] && |
| 82 [borderViewClass | 80 [borderViewClass |
| 83 instancesRespondToSelector:@selector(_drawTitleStringIn:withColor:)]; | 81 instancesRespondToSelector:@selector(_drawTitleStringIn:withColor:)]; |
| 84 gCanGetCornerRadius = | 82 gCanGetCornerRadius = |
| 85 [borderViewClass | 83 [borderViewClass |
| 86 instancesRespondToSelector:@selector(roundedCornerRadius)]; | 84 instancesRespondToSelector:@selector(roundedCornerRadius)]; |
| 87 | |
| 88 // Add _shadowFlags. This is a method on NSThemeFrame, not on NSGrayFrame. | |
| 89 // NSThemeFrame is NSGrayFrame's superclass. | |
| 90 Class themeFrameClass = NSClassFromString(@"NSThemeFrame"); | |
| 91 DCHECK(themeFrameClass); | |
| 92 if (!themeFrameClass) return; | |
| 93 m0 = class_getInstanceMethod([self class], @selector(_shadowFlags)); | |
| 94 DCHECK(m0); | |
| 95 if (m0) { | |
| 96 BOOL didAdd = class_addMethod(themeFrameClass, | |
| 97 @selector(_shadowFlagsOriginal), | |
| 98 method_getImplementation(m0), | |
| 99 method_getTypeEncoding(m0)); | |
| 100 DCHECK(didAdd); | |
| 101 if (didAdd) { | |
| 102 Method m1 = class_getInstanceMethod(themeFrameClass, | |
| 103 @selector(_shadowFlags)); | |
| 104 Method m2 = class_getInstanceMethod(themeFrameClass, | |
| 105 @selector(_shadowFlagsOriginal)); | |
| 106 DCHECK(m1 && m2); | |
| 107 if (m1 && m2) { | |
| 108 method_exchangeImplementations(m1, m2); | |
| 109 } | |
| 110 } | |
| 111 } | |
| 112 } | 85 } |
| 113 | 86 |
| 114 - (id)initWithFrame:(NSRect)frame { | 87 - (id)initWithFrame:(NSRect)frame { |
| 115 // This class is not for instantiating. | 88 // This class is not for instantiating. |
| 116 [self doesNotRecognizeSelector:_cmd]; | 89 [self doesNotRecognizeSelector:_cmd]; |
| 117 return nil; | 90 return nil; |
| 118 } | 91 } |
| 119 | 92 |
| 120 - (id)initWithCoder:(NSCoder*)coder { | 93 - (id)initWithCoder:(NSCoder*)coder { |
| 121 // This class is not for instantiating. | 94 // This class is not for instantiating. |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 | 302 |
| 330 if (titleColor) | 303 if (titleColor) |
| 331 return titleColor; | 304 return titleColor; |
| 332 | 305 |
| 333 if (incognito) | 306 if (incognito) |
| 334 return [NSColor whiteColor]; | 307 return [NSColor whiteColor]; |
| 335 else | 308 else |
| 336 return [NSColor windowFrameTextColor]; | 309 return [NSColor windowFrameTextColor]; |
| 337 } | 310 } |
| 338 | 311 |
| 339 // When the compositor is active, the whole content area is transparent (with | |
| 340 // an OpenGL surface behind it), so Cocoa draws the shadow only around the | |
| 341 // toolbar area. | |
| 342 // Tell the window server that we want a shadow as if none of the content | |
| 343 // area is transparent. | |
| 344 - (NSUInteger)_shadowFlags { | |
| 345 // A slightly less intrusive hack would be to call | |
| 346 // _setContentHasShadow:NO on the window. That seems to be what Terminal.app | |
| 347 // is doing. However, it leads to this function returning 'code | 64', which | |
| 348 // doesn't do what we want. For some reason, it does the right thing in | |
| 349 // Terminal.app. | |
| 350 // TODO(thakis): Figure out why -_setContentHasShadow: works in Terminal.app | |
| 351 // and use that technique instead. http://crbug.com/53382 | |
| 352 | |
| 353 // If this isn't the window class we expect, then pass it on to the | |
| 354 // original implementation. | |
| 355 if (![[self window] isKindOfClass:[FramedBrowserWindow class]]) | |
| 356 return [self _shadowFlagsOriginal]; | |
| 357 | |
| 358 return [self _shadowFlagsOriginal] | 128; | |
| 359 } | |
| 360 | |
| 361 @end | 312 @end |
| OLD | NEW |