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

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

Issue 2363823003: [merge-m54] Mac: Hack around Sierra autolayout bug in the certificate viewer. (Closed)
Patch Set: Created 4 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/certificate_viewer_mac.h" 5 #import "chrome/browser/ui/cocoa/certificate_viewer_mac.h"
6 6
7 #include <Security/Security.h> 7 #include <Security/Security.h>
8 #include <SecurityInterface/SFCertificatePanel.h> 8 #include <SecurityInterface/SFCertificatePanel.h>
9 #import <objc/runtime.h>
9 #include <vector> 10 #include <vector>
10 11
11 #include "base/mac/foundation_util.h" 12 #include "base/mac/foundation_util.h"
13 #include "base/mac/mac_util.h"
12 #include "base/mac/scoped_cftyperef.h" 14 #include "base/mac/scoped_cftyperef.h"
13 #include "base/macros.h" 15 #include "base/macros.h"
14 #include "chrome/browser/certificate_viewer.h" 16 #include "chrome/browser/certificate_viewer.h"
15 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" 17 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
16 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h" 18 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h"
17 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con troller.h" 19 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_con troller.h"
18 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
19 #include "net/cert/x509_util_mac.h" 21 #include "net/cert/x509_util_mac.h"
20 #import "ui/base/cocoa/window_size_constants.h" 22 #import "ui/base/cocoa/window_size_constants.h"
21 23
22 class SSLCertificateViewerCocoaBridge; 24 class SSLCertificateViewerCocoaBridge;
23 25
26 namespace {
27
28 // The maximum height of the certificate panel. Imposed whenever Sierra's buggy
29 // autolayout algorithm tries to change it. Doesn't affect user resizes.
30 const CGFloat kMaxPanelSetFrameHeight = 400;
31
32 // Pointer to the real implementation of -[SFCertificatePanel setFrame:..]. This
33 // is cached so a correct lookup is performed before we add the override.
34 IMP g_real_certificate_panel_setframe = nullptr;
35
36 // Provide a workaround for a buggy autolayout algorithm in macOS Sierra when
37 // running Chrome linked against the 10.10 SDK on macOS 10.12.
38 // See http://crbug.com/643123 for more details.
39 // Note it's not possible to inherit from SFCertificatePanel without triggering
40 // *** Assertion failure in -[BrowserCrApplication
41 // _commonBeginModalSessionForWindow:relativeToWindow:modalDelegate:
42 // didEndSelector:contextInfo:], .../AppKit.subproj/NSApplication.m:4077
43 // After that assertion, the sheet simply refuses to continue loading.
44 // It's also not possible to swizzle the -setFrame: method because
45 // SFCertificatePanel doesn't define it. Attempting to swizzle that would
46 // replace the implementation on NSWindow and constrain all dialogs.
47 // So, provide a regular C method and append it to the SFCertificatePanel
48 // implementation using the objc runtime.
49 // TODO(tapted): Remove all of this when Chrome's SDK target gets bumped.
50 id SFCertificatePanelSetFrameOverride(id self,
51 SEL _cmd,
52 NSRect frame,
53 BOOL display,
54 BOOL animate) {
55 if (frame.size.height > kMaxPanelSetFrameHeight)
56 frame.size.height = kMaxPanelSetFrameHeight;
57
58 DCHECK(g_real_certificate_panel_setframe);
59 return g_real_certificate_panel_setframe(self, _cmd, frame, display, animate);
60 }
61
62 void MaybeConstrainPanelSizeForSierraBug() {
63 #if defined(MAC_OS_X_VERSION_10_11) && \
64 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
65 // This is known not to be required when linking against the 10.11 SDK. Early
66 // exit in that case but assume anything earlier is broken.
67 return;
68 #endif
69
70 // It's also not required when running on El Capitan or earlier.
71 if (base::mac::IsAtMostOS10_11() || g_real_certificate_panel_setframe)
72 return;
73
74 const SEL kSetFrame = @selector(setFrame:display:animate:);
75 Method real_method =
76 class_getInstanceMethod([SFCertificatePanel class], kSetFrame);
77 const char* type_encoding = method_getTypeEncoding(real_method);
78 g_real_certificate_panel_setframe = method_getImplementation(real_method);
79 DCHECK(g_real_certificate_panel_setframe);
80 IMP method = reinterpret_cast<IMP>(&SFCertificatePanelSetFrameOverride);
81 BOOL method_added = class_addMethod([SFCertificatePanel class], kSetFrame,
82 method, type_encoding);
83 DCHECK(method_added);
84 }
85
86 } // namespace
87
24 @interface SFCertificatePanel (SystemPrivate) 88 @interface SFCertificatePanel (SystemPrivate)
25 // A system-private interface that dismisses a panel whose sheet was started by 89 // A system-private interface that dismisses a panel whose sheet was started by
26 // -beginSheetForWindow: 90 // -beginSheetForWindow:
27 // modalDelegate: 91 // modalDelegate:
28 // didEndSelector: 92 // didEndSelector:
29 // contextInfo: 93 // contextInfo:
30 // certificates: 94 // certificates:
31 // showGroup: 95 // showGroup:
32 // as though the user clicked the button identified by returnCode. Verified 96 // as though the user clicked the button identified by returnCode. Verified
33 // present in 10.8. 97 // present in 10.8.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 constrainedWindow_ = 201 constrainedWindow_ =
138 CreateAndShowWebModalDialogMac(observer_.get(), webContents, self); 202 CreateAndShowWebModalDialogMac(observer_.get(), webContents, self);
139 } 203 }
140 204
141 - (NSWindow*)overlayWindow { 205 - (NSWindow*)overlayWindow {
142 return overlayWindow_; 206 return overlayWindow_;
143 } 207 }
144 208
145 - (void)showSheetForWindow:(NSWindow*)window { 209 - (void)showSheetForWindow:(NSWindow*)window {
146 overlayWindow_.reset([window retain]); 210 overlayWindow_.reset([window retain]);
211
212 MaybeConstrainPanelSizeForSierraBug();
213
147 [panel_ beginSheetForWindow:window 214 [panel_ beginSheetForWindow:window
148 modalDelegate:self 215 modalDelegate:self
149 didEndSelector:@selector(sheetDidEnd: 216 didEndSelector:@selector(sheetDidEnd:
150 returnCode: 217 returnCode:
151 context:) 218 context:)
152 contextInfo:NULL 219 contextInfo:NULL
153 certificates:certificates_ 220 certificates:certificates_
154 showGroup:YES]; 221 showGroup:YES];
155 } 222 }
156 223
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 return panel_; 266 return panel_;
200 } 267 }
201 268
202 - (void)onConstrainedWindowClosed { 269 - (void)onConstrainedWindowClosed {
203 panel_.reset(); 270 panel_.reset();
204 constrainedWindow_.reset(); 271 constrainedWindow_.reset();
205 [self release]; 272 [self release];
206 } 273 }
207 274
208 @end 275 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698