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.
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_