widget/cocoa/nsCocoaUtils.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsCocoaUtils_h_
     7 #define nsCocoaUtils_h_
     9 #import <Cocoa/Cocoa.h>
    11 #include "nsRect.h"
    12 #include "imgIContainer.h"
    13 #include "npapi.h"
    14 #include "nsTArray.h"
    16 // This must be the last include:
    17 #include "nsObjCExceptions.h"
    19 #include "mozilla/EventForwards.h"
    21 // Declare the backingScaleFactor method that we want to call
    22 // on NSView/Window/Screen objects, if they recognize it.
    23 @interface NSObject (BackingScaleFactorCategory)
    24 - (CGFloat)backingScaleFactor;
    25 @end
    27 class nsIWidget;
    29 namespace mozilla {
    30 namespace gfx {
    31 class SourceSurface;
    32 }
    33 }
    35 // Used to retain a Cocoa object for the remainder of a method's execution.
    36 class nsAutoRetainCocoaObject {
    37 public:
    38 nsAutoRetainCocoaObject(id anObject)
    39 {
    40   mObject = NS_OBJC_TRY_EXPR_ABORT([anObject retain]);
    41 }
    42 ~nsAutoRetainCocoaObject()
    43 {
    44   NS_OBJC_TRY_ABORT([mObject release]);
    45 }
    46 private:
    47   id mObject;  // [STRONG]
    48 };
    50 // Provide a local autorelease pool for the remainder of a method's execution.
    51 class nsAutoreleasePool {
    52 public:
    53   nsAutoreleasePool()
    54   {
    55     mLocalPool = [[NSAutoreleasePool alloc] init];
    56   }
    57   ~nsAutoreleasePool()
    58   {
    59     [mLocalPool release];
    60   }
    61 private:
    62   NSAutoreleasePool *mLocalPool;
    63 };
    65 @interface NSApplication (Undocumented)
    67 // Present in all versions of OS X from (at least) 10.2.8 through 10.5.
    68 - (BOOL)_isRunningModal;
    69 - (BOOL)_isRunningAppModal;
    71 // It's sometimes necessary to explicitly remove a window from the "window
    72 // cache" in order to deactivate it.  The "window cache" is an undocumented
    73 // subsystem, all of whose methods are included in the NSWindowCache category
    74 // of the NSApplication class (in header files generated using class-dump).
    75 // Present in all versions of OS X from (at least) 10.2.8 through 10.5.
    76 - (void)_removeWindowFromCache:(NSWindow *)aWindow;
    78 // Send an event to the current Cocoa app-modal session.  Present in all
    79 // versions of OS X from (at least) 10.2.8 through 10.5.
    80 - (void)_modalSession:(NSModalSession)aSession sendEvent:(NSEvent *)theEvent;
    82 // Present (and documented) on OS X 10.6 and above.  Not present before 10.6.
    83 // This declaration needed to avoid compiler warnings when compiling on 10.5
    84 // and below (or using the 10.5 SDK and below).
    85 - (void)setHelpMenu:(NSMenu *)helpMenu;
    87 @end
    89 struct KeyBindingsCommand
    90 {
    91   SEL selector;
    92   id data;
    93 };
    95 @interface NativeKeyBindingsRecorder : NSResponder
    96 {
    97 @private
    98   nsTArray<KeyBindingsCommand>* mCommands;
    99 }
   101 - (void)startRecording:(nsTArray<KeyBindingsCommand>&)aCommands;
   103 - (void)doCommandBySelector:(SEL)aSelector;
   105 - (void)insertText:(id)aString;
   107 @end // NativeKeyBindingsRecorder
   109 class nsCocoaUtils
   110 {
   111   typedef mozilla::gfx::SourceSurface SourceSurface;
   113 public:
   115   // Get the backing scale factor from an object that supports this selector
   116   // (NSView/Window/Screen, on 10.7 or later), returning 1.0 if not supported
   117   static CGFloat
   118   GetBackingScaleFactor(id aObject)
   119   {
   120     if (HiDPIEnabled() &&
   121         [aObject respondsToSelector:@selector(backingScaleFactor)]) {
   122       return [aObject backingScaleFactor];
   123     }
   124     return 1.0;
   125   }
   127   // Conversions between Cocoa points and device pixels, given the backing
   128   // scale factor from a view/window/screen.
   129   static int32_t
   130   CocoaPointsToDevPixels(CGFloat aPts, CGFloat aBackingScale)
   131   {
   132     return NSToIntRound(aPts * aBackingScale);
   133   }
   135   static nsIntPoint
   136   CocoaPointsToDevPixels(const NSPoint& aPt, CGFloat aBackingScale)
   137   {
   138     return nsIntPoint(NSToIntRound(aPt.x * aBackingScale),
   139                       NSToIntRound(aPt.y * aBackingScale));
   140   }
   142   static nsIntRect
   143   CocoaPointsToDevPixels(const NSRect& aRect, CGFloat aBackingScale)
   144   {
   145     return nsIntRect(NSToIntRound(aRect.origin.x * aBackingScale),
   146                      NSToIntRound(aRect.origin.y * aBackingScale),
   147                      NSToIntRound(aRect.size.width * aBackingScale),
   148                      NSToIntRound(aRect.size.height * aBackingScale));
   149   }
   151   static CGFloat
   152   DevPixelsToCocoaPoints(int32_t aPixels, CGFloat aBackingScale)
   153   {
   154     return (CGFloat)aPixels / aBackingScale;
   155   }
   157   static NSPoint
   158   DevPixelsToCocoaPoints(const nsIntPoint& aPt, CGFloat aBackingScale)
   159   {
   160     return NSMakePoint((CGFloat)aPt.x / aBackingScale,
   161                        (CGFloat)aPt.y / aBackingScale);
   162   }
   164   static NSRect
   165   DevPixelsToCocoaPoints(const nsIntRect& aRect, CGFloat aBackingScale)
   166   {
   167     return NSMakeRect((CGFloat)aRect.x / aBackingScale,
   168                       (CGFloat)aRect.y / aBackingScale,
   169                       (CGFloat)aRect.width / aBackingScale,
   170                       (CGFloat)aRect.height / aBackingScale);
   171   }
   173   // Returns the given y coordinate, which must be in screen coordinates,
   174   // flipped from Gecko to Cocoa or Cocoa to Gecko.
   175   static float FlippedScreenY(float y);
   177   // The following functions come in "DevPix" variants that work with
   178   // backing-store (device pixel) coordinates, as well as the original
   179   // versions that expect coordinates in Cocoa points/CSS pixels.
   180   // The difference becomes important in HiDPI display modes, where Cocoa
   181   // points and backing-store pixels are no longer 1:1.
   183   // Gecko rects (nsRect) contain an origin (x,y) in a coordinate
   184   // system with (0,0) in the top-left of the primary screen. Cocoa rects
   185   // (NSRect) contain an origin (x,y) in a coordinate system with (0,0)
   186   // in the bottom-left of the primary screen. Both nsRect and NSRect
   187   // contain width/height info, with no difference in their use.
   188   // This function does no scaling, so the Gecko coordinates are
   189   // expected to be CSS pixels, which we treat as equal to Cocoa points.
   190   static NSRect GeckoRectToCocoaRect(const nsIntRect &geckoRect);
   192   // Converts aGeckoRect in dev pixels to points in Cocoa coordinates
   193   static NSRect GeckoRectToCocoaRectDevPix(const nsIntRect &aGeckoRect,
   194                                            CGFloat aBackingScale);
   196   // See explanation for geckoRectToCocoaRect, guess what this does...
   197   static nsIntRect CocoaRectToGeckoRect(const NSRect &cocoaRect);
   199   static nsIntRect CocoaRectToGeckoRectDevPix(const NSRect &aCocoaRect,
   200                                               CGFloat aBackingScale);
   202   // Gives the location for the event in screen coordinates. Do not call this
   203   // unless the window the event was originally targeted at is still alive!
   204   // anEvent may be nil -- in that case the current mouse location is returned.
   205   static NSPoint ScreenLocationForEvent(NSEvent* anEvent);
   207   // Determines if an event happened over a window, whether or not the event
   208   // is for the window. Does not take window z-order into account.
   209   static BOOL IsEventOverWindow(NSEvent* anEvent, NSWindow* aWindow);
   211   // Events are set up so that their coordinates refer to the window to which they
   212   // were originally sent. If we reroute the event somewhere else, we'll have
   213   // to get the window coordinates this way. Do not call this unless the window
   214   // the event was originally targeted at is still alive!
   215   static NSPoint EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow);
   217   static BOOL IsMomentumScrollEvent(NSEvent* aEvent);
   219   // Hides the Menu bar and the Dock. Multiple hide/show requests can be nested.
   220   static void HideOSChromeOnScreen(bool aShouldHide, NSScreen* aScreen);
   222   static nsIWidget* GetHiddenWindowWidget();
   224   static void PrepareForNativeAppModalDialog();
   225   static void CleanUpAfterNativeAppModalDialog();
   227   // 3 utility functions to go from a frame of imgIContainer to CGImage and then to NSImage
   228   // Convert imgIContainer -> CGImageRef, caller owns result
   230   /** Creates a <code>CGImageRef</code> from a frame contained in an <code>imgIContainer</code>.
   231       Copies the pixel data from the indicated frame of the <code>imgIContainer</code> into a new <code>CGImageRef</code>.
   232       The caller owns the <code>CGImageRef</code>. 
   233       @param aFrame the frame to convert
   234       @param aResult the resulting CGImageRef
   235       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
   236    */
   237   static nsresult CreateCGImageFromSurface(SourceSurface* aSurface,
   238                                            CGImageRef* aResult);
   240   /** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>.
   241       Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>.
   242       The caller owns the <code>NSImage</code>. 
   243       @param aInputImage the image to convert
   244       @param aResult the resulting NSImage
   245       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
   246    */
   247   static nsresult CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult);
   249   /** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>.
   250       Combines the two methods above. The caller owns the <code>NSImage</code>.
   251       @param aImage the image to extract a frame from
   252       @param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
   253       @param aResult the resulting NSImage
   254       @param scaleFactor the desired scale factor of the NSImage (2 for a retina display)
   255       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
   256    */  
   257   static nsresult CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult, CGFloat scaleFactor);
   259   /**
   260    * Returns nsAString for aSrc.
   261    */
   262   static void GetStringForNSString(const NSString *aSrc, nsAString& aDist);
   264   /**
   265    * Makes NSString instance for aString.
   266    */
   267   static NSString* ToNSString(const nsAString& aString);
   269   /**
   270    * Returns NSRect for aGeckoRect.
   271    * Just copies values between the two types; it does no coordinate-system
   272    * conversion, so both rects must have the same coordinate origin/direction.
   273    */
   274   static void GeckoRectToNSRect(const nsIntRect& aGeckoRect,
   275                                 NSRect& aOutCocoaRect);
   277   /**
   278    * Returns Gecko rect for aCocoaRect.
   279    * Just copies values between the two types; it does no coordinate-system
   280    * conversion, so both rects must have the same coordinate origin/direction.
   281    */
   282   static void NSRectToGeckoRect(const NSRect& aCocoaRect,
   283                                 nsIntRect& aOutGeckoRect);
   285   /**
   286    * Makes NSEvent instance for aEventTytpe and aEvent.
   287    */
   288   static NSEvent* MakeNewCocoaEventWithType(NSEventType aEventType,
   289                                             NSEvent *aEvent);
   291   /**
   292    * Initializes aNPCocoaEvent.
   293    */
   294   static void InitNPCocoaEvent(NPCocoaEvent* aNPCocoaEvent);
   296   /**
   297    * Initializes aPluginEvent for aCocoaEvent.
   298    */
   299   static void InitPluginEvent(mozilla::WidgetPluginEvent &aPluginEvent,
   300                               NPCocoaEvent &aCocoaEvent);
   301   /**
   302    * Initializes WidgetInputEvent for aNativeEvent or aModifiers.
   303    */
   304   static void InitInputEvent(mozilla::WidgetInputEvent &aInputEvent,
   305                              NSEvent* aNativeEvent);
   306   static void InitInputEvent(mozilla::WidgetInputEvent &aInputEvent,
   307                              NSUInteger aModifiers);
   309   /**
   310    * ConvertToCarbonModifier() returns carbon modifier flags for the cocoa
   311    * modifier flags.
   312    * NOTE: The result never includes right*Key.
   313    */
   314   static UInt32 ConvertToCarbonModifier(NSUInteger aCocoaModifier);
   316   /**
   317    * Whether to support HiDPI rendering. For testing purposes, to be removed
   318    * once we're comfortable with the HiDPI behavior.
   319    */
   320   static bool HiDPIEnabled();
   322   /**
   323    * Keys can optionally be bound by system or user key bindings to one or more
   324    * commands based on selectors. This collects any such commands in the
   325    * provided array.
   326    */
   327   static void GetCommandsFromKeyEvent(NSEvent* aEvent,
   328                                       nsTArray<KeyBindingsCommand>& aCommands);
   330   /**
   331    * Converts the string name of a Gecko key (like "VK_HOME") to the
   332    * corresponding Cocoa Unicode character.
   333    */
   334   static uint32_t ConvertGeckoNameToMacCharCode(const nsAString& aKeyCodeName);
   336   /**
   337    * Converts a Gecko key code (like NS_VK_HOME) to the corresponding Cocoa
   338    * Unicode character.
   339    */
   340   static uint32_t ConvertGeckoKeyCodeToMacCharCode(uint32_t aKeyCode);
   341 };
   343 #endif // nsCocoaUtils_h_

mercurial