Bug 1400057 - Override _wantsFloatingTitlebar to return NO in order to avoid titlebar glitches on 10.13. r?spohl
MozReview-Commit-ID: 4HffFOSqWxl
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -2901,16 +2901,17 @@ nsCocoaWindow::GetEditCommands(NativeKey
}
}
@end
@interface NSView(FrameViewMethodSwizzling)
- (NSPoint)FrameView__closeButtonOrigin;
- (NSPoint)FrameView__fullScreenButtonOrigin;
+- (BOOL)FrameView__wantsFloatingTitlebar;
@end
@implementation NSView(FrameViewMethodSwizzling)
- (NSPoint)FrameView__closeButtonOrigin
{
NSPoint defaultPosition = [self FrameView__closeButtonOrigin];
if ([[self window] isKindOfClass:[ToolbarWindow class]]) {
@@ -2923,16 +2924,21 @@ nsCocoaWindow::GetEditCommands(NativeKey
{
NSPoint defaultPosition = [self FrameView__fullScreenButtonOrigin];
if ([[self window] isKindOfClass:[ToolbarWindow class]]) {
return [(ToolbarWindow*)[self window] fullScreenButtonPositionWithDefaultPosition:defaultPosition];
}
return defaultPosition;
}
+- (BOOL)FrameView__wantsFloatingTitlebar
+{
+ return NO;
+}
+
@end
static NSMutableSet *gSwizzledFrameViewClasses = nil;
@interface NSWindow(PrivateSetNeedsDisplayInRectMethod)
- (void)_setNeedsDisplayInRect:(NSRect)aRect;
@end
@@ -2998,16 +3004,19 @@ static NSMutableSet *gSwizzledFrameViewC
}
// The frame of a window is implemented using undocumented NSView subclasses.
// We offset the window buttons by overriding the methods _closeButtonOrigin
// and _fullScreenButtonOrigin on these frame view classes. The class which is
// used for a window is determined in the window's frameViewClassForStyleMask:
// method, so this is where we make sure that we have swizzled the method on
// all encountered classes.
+// We also override the _wantsFloatingTitlebar method to return NO in order to
+// avoid some glitches in the titlebar that are caused by the way we mess with
+// the window.
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
{
Class frameViewClass = [super frameViewClassForStyleMask:styleMask];
if (!gSwizzledFrameViewClasses) {
gSwizzledFrameViewClasses = [[NSMutableSet setWithCapacity:3] retain];
if (!gSwizzledFrameViewClasses) {
return frameViewClass;
@@ -3015,16 +3024,19 @@ static NSMutableSet *gSwizzledFrameViewC
}
static IMP our_closeButtonOrigin =
class_getMethodImplementation([NSView class],
@selector(FrameView__closeButtonOrigin));
static IMP our_fullScreenButtonOrigin =
class_getMethodImplementation([NSView class],
@selector(FrameView__fullScreenButtonOrigin));
+ static IMP our_wantsFloatingTitlebar =
+ class_getMethodImplementation([NSView class],
+ @selector(FrameView__wantsFloatingTitlebar));
if (![gSwizzledFrameViewClasses containsObject:frameViewClass]) {
// Either of these methods might be implemented in both a subclass of
// NSFrameView and one of its own subclasses. Which means that if we
// aren't careful we might end up swizzling the same method twice.
// Since method swizzling involves swapping pointers, this would break
// things.
IMP _closeButtonOrigin =
@@ -3037,16 +3049,24 @@ static NSMutableSet *gSwizzledFrameViewC
IMP _fullScreenButtonOrigin =
class_getMethodImplementation(frameViewClass,
@selector(_fullScreenButtonOrigin));
if (_fullScreenButtonOrigin &&
_fullScreenButtonOrigin != our_fullScreenButtonOrigin) {
nsToolkit::SwizzleMethods(frameViewClass, @selector(_fullScreenButtonOrigin),
@selector(FrameView__fullScreenButtonOrigin));
}
+ IMP _wantsFloatingTitlebar =
+ class_getMethodImplementation(frameViewClass,
+ @selector(_wantsFloatingTitlebar));
+ if (_wantsFloatingTitlebar &&
+ _wantsFloatingTitlebar != our_wantsFloatingTitlebar) {
+ nsToolkit::SwizzleMethods(frameViewClass, @selector(_wantsFloatingTitlebar),
+ @selector(FrameView__wantsFloatingTitlebar));
+ }
[gSwizzledFrameViewClasses addObject:frameViewClass];
}
return frameViewClass;
}
- (id)initWithContentRect:(NSRect)aContentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)aBufferingType defer:(BOOL)aFlag
{