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>
12 #include "imgIContainer.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
;
27 // When building with a pre-10.7 SDK, NSEventPhase is not defined.
28 #if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
31 NSEventPhaseBegan
= 0x1 << 0,
32 NSEventPhaseStationary
= 0x1 << 1,
33 NSEventPhaseChanged
= 0x1 << 2,
34 NSEventPhaseEnded
= 0x1 << 3,
35 NSEventPhaseCancelled
= 0x1 << 4,
37 typedef NSUInteger NSEventPhase
;
38 #endif // #if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
40 #if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
42 NSEventPhaseMayBegin
= 0x1 << 5
44 #endif // #if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
54 // Used to retain a Cocoa object for the remainder of a method's execution.
55 class nsAutoRetainCocoaObject
{
57 explicit nsAutoRetainCocoaObject(id anObject
)
59 mObject
= NS_OBJC_TRY_EXPR_ABORT([anObject retain
]);
61 ~nsAutoRetainCocoaObject()
63 NS_OBJC_TRY_ABORT([mObject release
]);
66 id mObject
; // [STRONG]
69 // Provide a local autorelease pool for the remainder of a method's execution.
70 class nsAutoreleasePool
{
74 mLocalPool
= [[NSAutoreleasePool alloc
] init
];
81 NSAutoreleasePool
*mLocalPool
;
84 @interface
NSApplication (Undocumented
)
86 // Present in all versions of OS X from (at least) 10.2.8 through 10.5.
87 - (BOOL
)_isRunningModal
;
88 - (BOOL
)_isRunningAppModal
;
90 // It's sometimes necessary to explicitly remove a window from the "window
91 // cache" in order to deactivate it. The "window cache" is an undocumented
92 // subsystem, all of whose methods are included in the NSWindowCache category
93 // of the NSApplication class (in header files generated using class-dump).
94 // Present in all versions of OS X from (at least) 10.2.8 through 10.5.
95 - (void)_removeWindowFromCache
:(NSWindow
*)aWindow
;
97 // Send an event to the current Cocoa app-modal session. Present in all
98 // versions of OS X from (at least) 10.2.8 through 10.5.
99 - (void)_modalSession
:(NSModalSession
)aSession sendEvent
:(NSEvent
*)theEvent
;
101 // Present (and documented) on OS X 10.6 and above. Not present before 10.6.
102 // This declaration needed to avoid compiler warnings when compiling on 10.5
103 // and below (or using the 10.5 SDK and below).
104 - (void)setHelpMenu
:(NSMenu
*)helpMenu
;
108 struct KeyBindingsCommand
114 @interface NativeKeyBindingsRecorder
: NSResponder
117 nsTArray
<KeyBindingsCommand
>* mCommands
;
120 - (void)startRecording
:(nsTArray
<KeyBindingsCommand
>&)aCommands
;
122 - (void)doCommandBySelector
:(SEL
)aSelector
;
124 - (void)insertText
:(id
)aString
;
126 @end
// NativeKeyBindingsRecorder
130 typedef mozilla::gfx::SourceSurface SourceSurface
;
134 // Get the backing scale factor from an object that supports this selector
135 // (NSView/Window/Screen, on 10.7 or later), returning 1.0 if not supported
137 GetBackingScaleFactor(id aObject
)
139 if (HiDPIEnabled() &&
140 [aObject respondsToSelector
:@
selector(backingScaleFactor
)]) {
141 return [aObject backingScaleFactor
];
146 // Conversions between Cocoa points and device pixels, given the backing
147 // scale factor from a view/window/screen.
149 CocoaPointsToDevPixels(CGFloat aPts
, CGFloat aBackingScale
)
151 return NSToIntRound(aPts
* aBackingScale
);
155 CocoaPointsToDevPixels(const NSPoint
& aPt
, CGFloat aBackingScale
)
157 return nsIntPoint(NSToIntRound(aPt
.x
* aBackingScale
),
158 NSToIntRound(aPt
.y
* aBackingScale
));
162 CocoaPointsToDevPixels(const NSRect
& aRect
, CGFloat aBackingScale
)
164 return nsIntRect(NSToIntRound(aRect
.origin
.x
* aBackingScale
),
165 NSToIntRound(aRect
.origin
.y
* aBackingScale
),
166 NSToIntRound(aRect
.size
.width
* aBackingScale
),
167 NSToIntRound(aRect
.size
.height
* aBackingScale
));
171 DevPixelsToCocoaPoints(int32_t aPixels
, CGFloat aBackingScale
)
173 return (CGFloat
)aPixels
/ aBackingScale
;
177 DevPixelsToCocoaPoints(const nsIntPoint
& aPt
, CGFloat aBackingScale
)
179 return NSMakePoint((CGFloat
)aPt
.x
/ aBackingScale
,
180 (CGFloat
)aPt
.y
/ aBackingScale
);
184 DevPixelsToCocoaPoints(const nsIntRect
& aRect
, CGFloat aBackingScale
)
186 return NSMakeRect((CGFloat
)aRect
.x
/ aBackingScale
,
187 (CGFloat
)aRect
.y
/ aBackingScale
,
188 (CGFloat
)aRect
.width
/ aBackingScale
,
189 (CGFloat
)aRect
.height
/ aBackingScale
);
192 // Returns the given y coordinate, which must be in screen coordinates,
193 // flipped from Gecko to Cocoa or Cocoa to Gecko.
194 static float FlippedScreenY(float y
);
196 // The following functions come in "DevPix" variants that work with
197 // backing-store (device pixel) coordinates, as well as the original
198 // versions that expect coordinates in Cocoa points/CSS pixels.
199 // The difference becomes important in HiDPI display modes, where Cocoa
200 // points and backing-store pixels are no longer 1:1.
202 // Gecko rects (nsRect) contain an origin (x,y) in a coordinate
203 // system with (0,0) in the top-left of the primary screen. Cocoa rects
204 // (NSRect) contain an origin (x,y) in a coordinate system with (0,0)
205 // in the bottom-left of the primary screen. Both nsRect and NSRect
206 // contain width/height info, with no difference in their use.
207 // This function does no scaling, so the Gecko coordinates are
208 // expected to be CSS pixels, which we treat as equal to Cocoa points.
209 static NSRect
GeckoRectToCocoaRect(const nsIntRect
&geckoRect
);
211 // Converts aGeckoRect in dev pixels to points in Cocoa coordinates
212 static NSRect
GeckoRectToCocoaRectDevPix(const nsIntRect
&aGeckoRect
,
213 CGFloat aBackingScale
);
215 // See explanation for geckoRectToCocoaRect, guess what this does...
216 static nsIntRect
CocoaRectToGeckoRect(const NSRect
&cocoaRect
);
218 static nsIntRect
CocoaRectToGeckoRectDevPix(const NSRect
&aCocoaRect
,
219 CGFloat aBackingScale
);
221 // Gives the location for the event in screen coordinates. Do not call this
222 // unless the window the event was originally targeted at is still alive!
223 // anEvent may be nil -- in that case the current mouse location is returned.
224 static NSPoint
ScreenLocationForEvent(NSEvent
* anEvent
);
226 // Determines if an event happened over a window, whether or not the event
227 // is for the window. Does not take window z-order into account.
228 static BOOL
IsEventOverWindow(NSEvent
* anEvent
, NSWindow
* aWindow
);
230 // Events are set up so that their coordinates refer to the window to which they
231 // were originally sent. If we reroute the event somewhere else, we'll have
232 // to get the window coordinates this way. Do not call this unless the window
233 // the event was originally targeted at is still alive!
234 static NSPoint
EventLocationForWindow(NSEvent
* anEvent
, NSWindow
* aWindow
);
236 // Compatibility wrappers for the -[NSEvent phase], -[NSEvent momentumPhase],
237 // -[NSEvent hasPreciseScrollingDeltas] and -[NSEvent scrollingDeltaX/Y] APIs
238 // that became availaible starting with the 10.7 SDK.
239 // All of these can be removed once we drop support for 10.6.
240 static NSEventPhase
EventPhase(NSEvent
* aEvent
);
241 static NSEventPhase
EventMomentumPhase(NSEvent
* aEvent
);
242 static BOOL
IsMomentumScrollEvent(NSEvent
* aEvent
);
243 static BOOL
HasPreciseScrollingDeltas(NSEvent
* aEvent
);
244 static void GetScrollingDeltas(NSEvent
* aEvent
, CGFloat
* aOutDeltaX
, CGFloat
* aOutDeltaY
);
246 // Hides the Menu bar and the Dock. Multiple hide/show requests can be nested.
247 static void HideOSChromeOnScreen(bool aShouldHide
, NSScreen
* aScreen
);
249 static nsIWidget
* GetHiddenWindowWidget();
251 static void PrepareForNativeAppModalDialog();
252 static void CleanUpAfterNativeAppModalDialog();
254 // 3 utility functions to go from a frame of imgIContainer to CGImage and then to NSImage
255 // Convert imgIContainer -> CGImageRef, caller owns result
257 /** Creates a <code>CGImageRef</code> from a frame contained in an <code>imgIContainer</code>.
258 Copies the pixel data from the indicated frame of the <code>imgIContainer</code> into a new <code>CGImageRef</code>.
259 The caller owns the <code>CGImageRef</code>.
260 @param aFrame the frame to convert
261 @param aResult the resulting CGImageRef
262 @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
264 static nsresult
CreateCGImageFromSurface(SourceSurface
* aSurface
,
265 CGImageRef
* aResult
);
267 /** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>.
268 Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>.
269 The caller owns the <code>NSImage</code>.
270 @param aInputImage the image to convert
271 @param aResult the resulting NSImage
272 @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
274 static nsresult
CreateNSImageFromCGImage(CGImageRef aInputImage
, NSImage
**aResult
);
276 /** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>.
277 Combines the two methods above. The caller owns the <code>NSImage</code>.
278 @param aImage the image to extract a frame from
279 @param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
280 @param aResult the resulting NSImage
281 @param scaleFactor the desired scale factor of the NSImage (2 for a retina display)
282 @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
284 static nsresult
CreateNSImageFromImageContainer(imgIContainer
*aImage
, uint32_t aWhichFrame
, NSImage
**aResult
, CGFloat scaleFactor
);
287 * Returns nsAString for aSrc.
289 static void GetStringForNSString(const NSString
*aSrc
, nsAString
& aDist
);
292 * Makes NSString instance for aString.
294 static NSString
* ToNSString(const nsAString
& aString
);
297 * Returns NSRect for aGeckoRect.
298 * Just copies values between the two types; it does no coordinate-system
299 * conversion, so both rects must have the same coordinate origin/direction.
301 static void GeckoRectToNSRect(const nsIntRect
& aGeckoRect
,
302 NSRect
& aOutCocoaRect
);
305 * Returns Gecko rect for aCocoaRect.
306 * Just copies values between the two types; it does no coordinate-system
307 * conversion, so both rects must have the same coordinate origin/direction.
309 static void NSRectToGeckoRect(const NSRect
& aCocoaRect
,
310 nsIntRect
& aOutGeckoRect
);
313 * Makes NSEvent instance for aEventTytpe and aEvent.
315 static NSEvent
* MakeNewCocoaEventWithType(NSEventType aEventType
,
319 * Initializes aNPCocoaEvent.
321 static void InitNPCocoaEvent(NPCocoaEvent
* aNPCocoaEvent
);
324 * Initializes aPluginEvent for aCocoaEvent.
326 static void InitPluginEvent(mozilla::WidgetPluginEvent
&aPluginEvent
,
327 NPCocoaEvent
&aCocoaEvent
);
329 * Initializes WidgetInputEvent for aNativeEvent or aModifiers.
331 static void InitInputEvent(mozilla::WidgetInputEvent
&aInputEvent
,
332 NSEvent
* aNativeEvent
);
333 static void InitInputEvent(mozilla::WidgetInputEvent
&aInputEvent
,
334 NSUInteger aModifiers
);
337 * ConvertToCarbonModifier() returns carbon modifier flags for the cocoa
339 * NOTE: The result never includes right*Key.
341 static UInt32
ConvertToCarbonModifier(NSUInteger aCocoaModifier
);
344 * Whether to support HiDPI rendering. For testing purposes, to be removed
345 * once we're comfortable with the HiDPI behavior.
347 static bool HiDPIEnabled();
350 * Keys can optionally be bound by system or user key bindings to one or more
351 * commands based on selectors. This collects any such commands in the
354 static void GetCommandsFromKeyEvent(NSEvent
* aEvent
,
355 nsTArray
<KeyBindingsCommand
>& aCommands
);
358 * Converts the string name of a Gecko key (like "VK_HOME") to the
359 * corresponding Cocoa Unicode character.
361 static uint32_t ConvertGeckoNameToMacCharCode(const nsAString
& aKeyCodeName
);
364 * Converts a Gecko key code (like NS_VK_HOME) to the corresponding Cocoa
367 static uint32_t ConvertGeckoKeyCodeToMacCharCode(uint32_t aKeyCode
);
370 #endif // nsCocoaUtils_h_