Bug 1400057 - Override _wantsFloatingTitlebar to return NO in order to avoid titlebar glitches on 10.13. r?spohl draft
authorMarkus Stange <mstange@themasta.com>
Fri, 29 Sep 2017 16:49:30 -0400
changeset 672864 000939d900cc4f96f5f2c879502aac271f4ba971
parent 672850 ac1719be7ff52aa99b9b1087711397f6101b7abd
child 733945 130393b68fe391302c68ec76506c4f342e64cd1a
push id82398
push userbmo:mstange@themasta.com
push dateFri, 29 Sep 2017 20:50:18 +0000
reviewersspohl
bugs1400057
milestone58.0a1
Bug 1400057 - Override _wantsFloatingTitlebar to return NO in order to avoid titlebar glitches on 10.13. r?spohl MozReview-Commit-ID: 4HffFOSqWxl
widget/cocoa/nsCocoaWindow.mm
--- 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
 {