BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / custom_frame_view.mm
bloba745822fd502a9ce933ce18b2ec957f71a3e91dc
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
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/custom_frame_view.h"
7 #import <Carbon/Carbon.h>
8 #include <crt_externs.h>
9 #import <objc/runtime.h>
10 #include <string.h>
12 #include "base/logging.h"
13 #include "base/mac/mac_util.h"
14 #include "base/mac/scoped_nsautorelease_pool.h"
16 @interface NSView (Swizzles)
17 - (NSPoint)_fullScreenButtonOriginOriginal;
18 @end
20 @interface NSWindow (FramedBrowserWindow)
21 - (NSPoint)fullScreenButtonOriginAdjustment;
22 @end
24 @interface CustomFrameView : NSView
26 // Clang emits a warning if designated initializers don't call the super
27 // initializer, even if the method raises an exception.
28 // http://www.crbug.com/479019.
29 - (id)initWithFrame:(NSRect)frame UNAVAILABLE_ATTRIBUTE;
30 - (id)initWithCoder:(NSCoder*)coder UNAVAILABLE_ATTRIBUTE;
32 @end
34 @implementation CustomFrameView
36 + (void)load {
37   // Swizzling should only happen in the browser process. Interacting with
38   // AppKit will run +[borderViewClass initialize] in the renderer, which
39   // may establish Mach IPC with com.apple.windowserver.
40   // Note that CommandLine has not been initialized yet, since this is running
41   // as a module initializer.
42   const char* const* const argv = *_NSGetArgv();
43   const int argc = *_NSGetArgc();
44   const char kType[] = "--type=";
45   for (int i = 1; i < argc; ++i) {
46     const char* arg = argv[i];
47     if (strncmp(arg, kType, strlen(kType)) == 0)
48       return;
49   }
51   // In Yosemite, the fullscreen button replaces the zoom button. We no longer
52   // need to swizzle out this AppKit private method.
53   if (!base::mac::IsOSMavericksOrEarlier())
54     return;
56   base::mac::ScopedNSAutoreleasePool pool;
58   // On 10.8+ the background for textured windows are no longer drawn by
59   // NSGrayFrame, and NSThemeFrame is used instead <http://crbug.com/114745>.
60   Class borderViewClass = NSClassFromString(
61       base::mac::IsOSMountainLionOrLater() ? @"NSThemeFrame" : @"NSGrayFrame");
62   DCHECK(borderViewClass);
63   if (!borderViewClass) return;
65   // Swizzle the method that sets the origin for the Lion fullscreen button.
66   // Do nothing if it cannot be found.
67   Method m0 = class_getInstanceMethod([self class],
68                                @selector(_fullScreenButtonOrigin));
69   if (m0) {
70     BOOL didAdd = class_addMethod(borderViewClass,
71                                   @selector(_fullScreenButtonOriginOriginal),
72                                   method_getImplementation(m0),
73                                   method_getTypeEncoding(m0));
74     if (didAdd) {
75       Method m1 = class_getInstanceMethod(borderViewClass,
76                                           @selector(_fullScreenButtonOrigin));
77       Method m2 = class_getInstanceMethod(
78           borderViewClass, @selector(_fullScreenButtonOriginOriginal));
79       if (m1 && m2) {
80         method_exchangeImplementations(m1, m2);
81       }
82     }
83   }
86 - (id)initWithFrame:(NSRect)frame {
87   // This class is not for instantiating.
88   [self doesNotRecognizeSelector:_cmd];
89   return nil;
92 - (id)initWithCoder:(NSCoder*)coder {
93   // This class is not for instantiating.
94   [self doesNotRecognizeSelector:_cmd];
95   return nil;
98 // Override to move the fullscreen button to the left of the profile avatar.
99 - (NSPoint)_fullScreenButtonOrigin {
100   NSWindow* window = [self window];
101   NSPoint offset = NSZeroPoint;
103   if ([window respondsToSelector:@selector(fullScreenButtonOriginAdjustment)])
104     offset = [window fullScreenButtonOriginAdjustment];
106   NSPoint origin = [self _fullScreenButtonOriginOriginal];
107   origin.x += offset.x;
108   origin.y += offset.y;
109   return origin;
112 @end