Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: chrome/browser/ui/cocoa/custom_frame_view.mm

Issue 915313002: [Mac] Remove -[NSWindow drawRect] swizzling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@nawc
Patch Set: Update test. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/custom_frame_view.h" 5 #import "chrome/browser/ui/cocoa/custom_frame_view.h"
6 6
7 #import <Carbon/Carbon.h> 7 #import <Carbon/Carbon.h>
8 #include <crt_externs.h> 8 #include <crt_externs.h>
9 #import <objc/runtime.h> 9 #import <objc/runtime.h>
10 #include <string.h> 10 #include <string.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac/mac_util.h" 13 #include "base/mac/mac_util.h"
14 #include "base/mac/scoped_nsautorelease_pool.h" 14 #include "base/mac/scoped_nsautorelease_pool.h"
15 15
16 namespace {
17 BOOL gCanDrawTitle = NO;
18 BOOL gCanGetCornerRadius = NO;
19 } // namespace
20
21 @interface NSView (Swizzles) 16 @interface NSView (Swizzles)
22 - (void)drawRectOriginal:(NSRect)rect;
23 - (NSPoint)_fullScreenButtonOriginOriginal; 17 - (NSPoint)_fullScreenButtonOriginOriginal;
24 @end 18 @end
25 19
26 @interface NSWindow (FramedBrowserWindow) 20 @interface NSWindow (FramedBrowserWindow)
27 - (NSPoint)fullScreenButtonOriginAdjustment; 21 - (NSPoint)fullScreenButtonOriginAdjustment;
28 @end 22 @end
29 23
30 @implementation NSWindow (CustomFrameView)
31 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view {
32 [view drawRectOriginal:rect];
33 }
34 @end
35
36 @interface CustomFrameView : NSView 24 @interface CustomFrameView : NSView
37 25
38 @end 26 @end
39 27
40 @implementation CustomFrameView 28 @implementation CustomFrameView
41 29
42 // This is where we swizzle drawRect, and add in two methods that we
43 // need. If any of these fail it shouldn't affect the functionality of the
44 // others. If they all fail, we will lose window frame theming and
45 // roll overs for our close widgets, but things should still function
46 // correctly.
47 + (void)load { 30 + (void)load {
48 // Swizzling should only happen in the browser process. Interacting with 31 // Swizzling should only happen in the browser process. Interacting with
49 // AppKit will run +[borderViewClass initialize] in the renderer, which 32 // AppKit will run +[borderViewClass initialize] in the renderer, which
50 // may establish Mach IPC with com.apple.windowserver. 33 // may establish Mach IPC with com.apple.windowserver.
51 // Note that CommandLine has not been initialized yet, since this is running 34 // Note that CommandLine has not been initialized yet, since this is running
52 // as a module initializer. 35 // as a module initializer.
53 const char* const* const argv = *_NSGetArgv(); 36 const char* const* const argv = *_NSGetArgv();
54 const int argc = *_NSGetArgc(); 37 const int argc = *_NSGetArgc();
55 const char kType[] = "--type="; 38 const char kType[] = "--type=";
56 for (int i = 1; i < argc; ++i) { 39 for (int i = 1; i < argc; ++i) {
57 const char* arg = argv[i]; 40 const char* arg = argv[i];
58 if (strncmp(arg, kType, strlen(kType)) == 0) 41 if (strncmp(arg, kType, strlen(kType)) == 0)
59 return; 42 return;
60 } 43 }
61 44
62 base::mac::ScopedNSAutoreleasePool pool; 45 base::mac::ScopedNSAutoreleasePool pool;
63 46
64 // On 10.8+ the background for textured windows are no longer drawn by 47 // On 10.8+ the background for textured windows are no longer drawn by
65 // NSGrayFrame, and NSThemeFrame is used instead <http://crbug.com/114745>. 48 // NSGrayFrame, and NSThemeFrame is used instead <http://crbug.com/114745>.
66 Class borderViewClass = NSClassFromString( 49 Class borderViewClass = NSClassFromString(
67 base::mac::IsOSMountainLionOrLater() ? @"NSThemeFrame" : @"NSGrayFrame"); 50 base::mac::IsOSMountainLionOrLater() ? @"NSThemeFrame" : @"NSGrayFrame");
68 DCHECK(borderViewClass); 51 DCHECK(borderViewClass);
69 if (!borderViewClass) return; 52 if (!borderViewClass) return;
70 53
71 // Exchange draw rect.
72 Method m0 = class_getInstanceMethod([self class], @selector(drawRect:));
73 DCHECK(m0);
74 if (m0) {
75 BOOL didAdd = class_addMethod(borderViewClass,
76 @selector(drawRectOriginal:),
77 method_getImplementation(m0),
78 method_getTypeEncoding(m0));
79 DCHECK(didAdd);
80 if (didAdd) {
81 Method m1 = class_getInstanceMethod(borderViewClass,
82 @selector(drawRect:));
83 Method m2 = class_getInstanceMethod(borderViewClass,
84 @selector(drawRectOriginal:));
85 DCHECK(m1 && m2);
86 if (m1 && m2) {
87 method_exchangeImplementations(m1, m2);
88 }
89 }
90 }
91
92 // In Yosemite, the fullscreen button replaces the zoom button. We no longer 54 // In Yosemite, the fullscreen button replaces the zoom button. We no longer
93 // need to swizzle out this AppKit private method. 55 // need to swizzle out this AppKit private method.
94 if (base::mac::IsOSMavericksOrEarlier()) { 56 if (base::mac::IsOSMavericksOrEarlier()) {
Robert Sesek 2015/03/04 19:16:26 Since we only swizzle in this case, you can move t
jackhou1 2015/03/05 04:28:08 Done.
95 // Swizzle the method that sets the origin for the Lion fullscreen button. 57 // Swizzle the method that sets the origin for the Lion fullscreen button.
96 // Do nothing if it cannot be found. 58 // Do nothing if it cannot be found.
97 m0 = class_getInstanceMethod([self class], 59 Method m0 = class_getInstanceMethod([self class],
98 @selector(_fullScreenButtonOrigin)); 60 @selector(_fullScreenButtonOrigin));
99 if (m0) { 61 if (m0) {
100 BOOL didAdd = class_addMethod(borderViewClass, 62 BOOL didAdd = class_addMethod(borderViewClass,
101 @selector(_fullScreenButtonOriginOriginal), 63 @selector(_fullScreenButtonOriginOriginal),
102 method_getImplementation(m0), 64 method_getImplementation(m0),
103 method_getTypeEncoding(m0)); 65 method_getTypeEncoding(m0));
104 if (didAdd) { 66 if (didAdd) {
105 Method m1 = class_getInstanceMethod(borderViewClass, 67 Method m1 = class_getInstanceMethod(borderViewClass,
106 @selector(_fullScreenButtonOrigin)); 68 @selector(_fullScreenButtonOrigin));
107 Method m2 = class_getInstanceMethod( 69 Method m2 = class_getInstanceMethod(
108 borderViewClass, @selector(_fullScreenButtonOriginOriginal)); 70 borderViewClass, @selector(_fullScreenButtonOriginOriginal));
109 if (m1 && m2) { 71 if (m1 && m2) {
110 method_exchangeImplementations(m1, m2); 72 method_exchangeImplementations(m1, m2);
111 } 73 }
112 } 74 }
113 } 75 }
114 } 76 }
115 } 77 }
116 78
117 + (BOOL)canDrawTitle {
118 return gCanDrawTitle;
119 }
120
121 + (BOOL)canGetCornerRadius {
122 return gCanGetCornerRadius;
123 }
124
125 - (id)initWithFrame:(NSRect)frame { 79 - (id)initWithFrame:(NSRect)frame {
126 // This class is not for instantiating. 80 // This class is not for instantiating.
127 [self doesNotRecognizeSelector:_cmd]; 81 [self doesNotRecognizeSelector:_cmd];
128 return nil; 82 return nil;
129 } 83 }
130 84
131 - (id)initWithCoder:(NSCoder*)coder { 85 - (id)initWithCoder:(NSCoder*)coder {
132 // This class is not for instantiating. 86 // This class is not for instantiating.
133 [self doesNotRecognizeSelector:_cmd]; 87 [self doesNotRecognizeSelector:_cmd];
134 return nil; 88 return nil;
135 } 89 }
136 90
137 // Here is our custom drawing for our frame.
138 - (void)drawRect:(NSRect)rect {
139 // Delegate drawing to the window, whose default implementation (above) is to
140 // call into the original implementation.
141 [[self window] drawCustomFrameRect:rect forView:self];
142 }
143
144 // Override to move the fullscreen button to the left of the profile avatar. 91 // Override to move the fullscreen button to the left of the profile avatar.
145 - (NSPoint)_fullScreenButtonOrigin { 92 - (NSPoint)_fullScreenButtonOrigin {
146 NSWindow* window = [self window]; 93 NSWindow* window = [self window];
147 NSPoint offset = NSZeroPoint; 94 NSPoint offset = NSZeroPoint;
148 95
149 if ([window respondsToSelector:@selector(fullScreenButtonOriginAdjustment)]) 96 if ([window respondsToSelector:@selector(fullScreenButtonOriginAdjustment)])
150 offset = [window fullScreenButtonOriginAdjustment]; 97 offset = [window fullScreenButtonOriginAdjustment];
151 98
152 NSPoint origin = [self _fullScreenButtonOriginOriginal]; 99 NSPoint origin = [self _fullScreenButtonOriginOriginal];
153 origin.x += offset.x; 100 origin.x += offset.x;
154 origin.y += offset.y; 101 origin.y += offset.y;
155 return origin; 102 return origin;
156 } 103 }
157 104
158 @end 105 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/custom_frame_view.h ('k') | chrome/browser/ui/cocoa/custom_frame_view_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698