Bug 1291457 - Allow the panel's NSWindow class to specify a native animation type for arrow panel opening and closing, and overriding that animation's origin. draft
authorMarkus Stange <mstange@themasta.com>
Tue, 02 Aug 2016 16:28:29 -0400
changeset 395775 23cb515d4b12144549b3a05bfe36337eb08959fd
parent 395774 94e453d1e5628acb81239e0823c19291783bf24a
child 395776 ca3c88de268845bb4d1fc47ff186cbe4f5e52123
push id24844
push usermstange@themasta.com
push dateTue, 02 Aug 2016 21:27:11 +0000
bugs1291457
milestone51.0a1
Bug 1291457 - Allow the panel's NSWindow class to specify a native animation type for arrow panel opening and closing, and overriding that animation's origin. This uses private APIs. The public API for native arrow panels doesn't map well to Gecko. MozReview-Commit-ID: 2zOTZ6jWlua
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -128,23 +128,26 @@ typedef struct _nsCocoaWindowList {
 + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
 
 @end
 
 @interface PopupWindow : BaseWindow
 {
 @private
   BOOL mIsContextMenu;
+  BOOL mIsArrowPanel;
+  NSPoint mArrowPanelArrowTip;
 }
 
 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
       backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation;
 - (BOOL)isContextMenu;
 - (void)setIsContextMenu:(BOOL)flag;
 - (BOOL)canBecomeMainWindow;
+- (void)setIsArrowPanel:(BOOL)aIsArrowPanel pointingTo:(NSPoint)aArrowTip;
 
 @end
 
 @interface BorderlessWindow : BaseWindow
 {
 }
 
 - (BOOL)canBecomeKeyWindow;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -3710,40 +3710,94 @@ TitlebarDrawCallback(void* aInfo, CGCont
 
 - (NSString*)colorSpaceName
 {
   return NSDeviceRGBColorSpace;
 }
 
 @end
 
+@interface NSWindow(WindowAnimation)
+- (NSInteger)_orderFrontAnimationType;
+- (NSInteger)_orderOutAnimationType;
+- (id)_windowTransformAnimationForOrdering:(NSInteger)aOrdering animationType:(NSInteger)aAnimationType interruptingAnimation:(id)aInterruptingAnimation;
+@end
+
+@interface NSObject(NSWindowTransformAnimationAnchorPoint)
+- (void)setAnchorPoint:(NSPoint)aPoint;
+@end
+
+enum NSWindowTransformAnimationType {
+  NSWindowTransformAnimationPopIn = 3,
+  NSWindowTransformAnimationPopOut,
+  NSWindowTransformAnimationScaleUpAndIn,
+  NSWindowTransformAnimationScaleDownAndOut,
+  NSWindowTransformAnimationScaleDownAndIn,
+  NSWindowTransformAnimationScaleUpAndOut,
+  NSWindowTransformAnimationSpringUpAndIn,
+  NSWindowTransformAnimationFallAndFadeOut,
+  NSWindowTransformAnimationFadeIn,
+  NSWindowTransformAnimationFadeOut,
+  NSWindowTransformAnimationShake,
+  NSWindowTransformAnimationDuplicate,
+  NSWindowTransformAnimationScaleUpAndDown,
+  NSWindowTransformAnimationShadowPop
+};
+
 @implementation PopupWindow
 
 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
       backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   mIsContextMenu = false;
+  mIsArrowPanel = false;
+  mArrowPanelArrowTip = NSZeroPoint;
   return [super initWithContentRect:contentRect styleMask:styleMask
           backing:bufferingType defer:deferCreation];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)isContextMenu
 {
   return mIsContextMenu;
 }
 
 - (void)setIsContextMenu:(BOOL)flag
 {
   mIsContextMenu = flag;
 }
 
+- (NSInteger)_orderFrontAnimationType
+{
+  return mIsArrowPanel ? NSWindowTransformAnimationPopIn : [super _orderFrontAnimationType];
+}
+
+- (NSInteger)_orderOutAnimationType
+{
+  return mIsArrowPanel ? NSWindowTransformAnimationFadeOut : [super _orderOutAnimationType];
+}
+
+- (id)_windowTransformAnimationForOrdering:(NSInteger)aOrdering animationType:(NSInteger)aAnimationType interruptingAnimation:(id)aInterruptingAnimation
+{
+  id animation = [super _windowTransformAnimationForOrdering:aOrdering animationType:aAnimationType interruptingAnimation:aInterruptingAnimation];
+  if (mIsArrowPanel && [animation respondsToSelector:@selector(setAnchorPoint:)]) {
+    [animation setAnchorPoint:NSMakePoint(mArrowPanelArrowTip.x, [self frame].size.height - mArrowPanelArrowTip.y)];
+  }
+  return animation;
+}
+
+- (void)setIsArrowPanel:(BOOL)aIsArrowPanel pointingTo:(NSPoint)aArrowTip
+{
+  mIsArrowPanel = aIsArrowPanel;
+  mArrowPanelArrowTip = aArrowTip;
+}
+
 - (BOOL)canBecomeMainWindow
 {
   // This is overriden because the default is 'yes' when a titlebar is present.
   return NO;
 }
 
 @end