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