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 |