1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/cocoa/nsCocoaUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,343 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsCocoaUtils_h_ 1.10 +#define nsCocoaUtils_h_ 1.11 + 1.12 +#import <Cocoa/Cocoa.h> 1.13 + 1.14 +#include "nsRect.h" 1.15 +#include "imgIContainer.h" 1.16 +#include "npapi.h" 1.17 +#include "nsTArray.h" 1.18 + 1.19 +// This must be the last include: 1.20 +#include "nsObjCExceptions.h" 1.21 + 1.22 +#include "mozilla/EventForwards.h" 1.23 + 1.24 +// Declare the backingScaleFactor method that we want to call 1.25 +// on NSView/Window/Screen objects, if they recognize it. 1.26 +@interface NSObject (BackingScaleFactorCategory) 1.27 +- (CGFloat)backingScaleFactor; 1.28 +@end 1.29 + 1.30 +class nsIWidget; 1.31 + 1.32 +namespace mozilla { 1.33 +namespace gfx { 1.34 +class SourceSurface; 1.35 +} 1.36 +} 1.37 + 1.38 +// Used to retain a Cocoa object for the remainder of a method's execution. 1.39 +class nsAutoRetainCocoaObject { 1.40 +public: 1.41 +nsAutoRetainCocoaObject(id anObject) 1.42 +{ 1.43 + mObject = NS_OBJC_TRY_EXPR_ABORT([anObject retain]); 1.44 +} 1.45 +~nsAutoRetainCocoaObject() 1.46 +{ 1.47 + NS_OBJC_TRY_ABORT([mObject release]); 1.48 +} 1.49 +private: 1.50 + id mObject; // [STRONG] 1.51 +}; 1.52 + 1.53 +// Provide a local autorelease pool for the remainder of a method's execution. 1.54 +class nsAutoreleasePool { 1.55 +public: 1.56 + nsAutoreleasePool() 1.57 + { 1.58 + mLocalPool = [[NSAutoreleasePool alloc] init]; 1.59 + } 1.60 + ~nsAutoreleasePool() 1.61 + { 1.62 + [mLocalPool release]; 1.63 + } 1.64 +private: 1.65 + NSAutoreleasePool *mLocalPool; 1.66 +}; 1.67 + 1.68 +@interface NSApplication (Undocumented) 1.69 + 1.70 +// Present in all versions of OS X from (at least) 10.2.8 through 10.5. 1.71 +- (BOOL)_isRunningModal; 1.72 +- (BOOL)_isRunningAppModal; 1.73 + 1.74 +// It's sometimes necessary to explicitly remove a window from the "window 1.75 +// cache" in order to deactivate it. The "window cache" is an undocumented 1.76 +// subsystem, all of whose methods are included in the NSWindowCache category 1.77 +// of the NSApplication class (in header files generated using class-dump). 1.78 +// Present in all versions of OS X from (at least) 10.2.8 through 10.5. 1.79 +- (void)_removeWindowFromCache:(NSWindow *)aWindow; 1.80 + 1.81 +// Send an event to the current Cocoa app-modal session. Present in all 1.82 +// versions of OS X from (at least) 10.2.8 through 10.5. 1.83 +- (void)_modalSession:(NSModalSession)aSession sendEvent:(NSEvent *)theEvent; 1.84 + 1.85 +// Present (and documented) on OS X 10.6 and above. Not present before 10.6. 1.86 +// This declaration needed to avoid compiler warnings when compiling on 10.5 1.87 +// and below (or using the 10.5 SDK and below). 1.88 +- (void)setHelpMenu:(NSMenu *)helpMenu; 1.89 + 1.90 +@end 1.91 + 1.92 +struct KeyBindingsCommand 1.93 +{ 1.94 + SEL selector; 1.95 + id data; 1.96 +}; 1.97 + 1.98 +@interface NativeKeyBindingsRecorder : NSResponder 1.99 +{ 1.100 +@private 1.101 + nsTArray<KeyBindingsCommand>* mCommands; 1.102 +} 1.103 + 1.104 +- (void)startRecording:(nsTArray<KeyBindingsCommand>&)aCommands; 1.105 + 1.106 +- (void)doCommandBySelector:(SEL)aSelector; 1.107 + 1.108 +- (void)insertText:(id)aString; 1.109 + 1.110 +@end // NativeKeyBindingsRecorder 1.111 + 1.112 +class nsCocoaUtils 1.113 +{ 1.114 + typedef mozilla::gfx::SourceSurface SourceSurface; 1.115 + 1.116 +public: 1.117 + 1.118 + // Get the backing scale factor from an object that supports this selector 1.119 + // (NSView/Window/Screen, on 10.7 or later), returning 1.0 if not supported 1.120 + static CGFloat 1.121 + GetBackingScaleFactor(id aObject) 1.122 + { 1.123 + if (HiDPIEnabled() && 1.124 + [aObject respondsToSelector:@selector(backingScaleFactor)]) { 1.125 + return [aObject backingScaleFactor]; 1.126 + } 1.127 + return 1.0; 1.128 + } 1.129 + 1.130 + // Conversions between Cocoa points and device pixels, given the backing 1.131 + // scale factor from a view/window/screen. 1.132 + static int32_t 1.133 + CocoaPointsToDevPixels(CGFloat aPts, CGFloat aBackingScale) 1.134 + { 1.135 + return NSToIntRound(aPts * aBackingScale); 1.136 + } 1.137 + 1.138 + static nsIntPoint 1.139 + CocoaPointsToDevPixels(const NSPoint& aPt, CGFloat aBackingScale) 1.140 + { 1.141 + return nsIntPoint(NSToIntRound(aPt.x * aBackingScale), 1.142 + NSToIntRound(aPt.y * aBackingScale)); 1.143 + } 1.144 + 1.145 + static nsIntRect 1.146 + CocoaPointsToDevPixels(const NSRect& aRect, CGFloat aBackingScale) 1.147 + { 1.148 + return nsIntRect(NSToIntRound(aRect.origin.x * aBackingScale), 1.149 + NSToIntRound(aRect.origin.y * aBackingScale), 1.150 + NSToIntRound(aRect.size.width * aBackingScale), 1.151 + NSToIntRound(aRect.size.height * aBackingScale)); 1.152 + } 1.153 + 1.154 + static CGFloat 1.155 + DevPixelsToCocoaPoints(int32_t aPixels, CGFloat aBackingScale) 1.156 + { 1.157 + return (CGFloat)aPixels / aBackingScale; 1.158 + } 1.159 + 1.160 + static NSPoint 1.161 + DevPixelsToCocoaPoints(const nsIntPoint& aPt, CGFloat aBackingScale) 1.162 + { 1.163 + return NSMakePoint((CGFloat)aPt.x / aBackingScale, 1.164 + (CGFloat)aPt.y / aBackingScale); 1.165 + } 1.166 + 1.167 + static NSRect 1.168 + DevPixelsToCocoaPoints(const nsIntRect& aRect, CGFloat aBackingScale) 1.169 + { 1.170 + return NSMakeRect((CGFloat)aRect.x / aBackingScale, 1.171 + (CGFloat)aRect.y / aBackingScale, 1.172 + (CGFloat)aRect.width / aBackingScale, 1.173 + (CGFloat)aRect.height / aBackingScale); 1.174 + } 1.175 + 1.176 + // Returns the given y coordinate, which must be in screen coordinates, 1.177 + // flipped from Gecko to Cocoa or Cocoa to Gecko. 1.178 + static float FlippedScreenY(float y); 1.179 + 1.180 + // The following functions come in "DevPix" variants that work with 1.181 + // backing-store (device pixel) coordinates, as well as the original 1.182 + // versions that expect coordinates in Cocoa points/CSS pixels. 1.183 + // The difference becomes important in HiDPI display modes, where Cocoa 1.184 + // points and backing-store pixels are no longer 1:1. 1.185 + 1.186 + // Gecko rects (nsRect) contain an origin (x,y) in a coordinate 1.187 + // system with (0,0) in the top-left of the primary screen. Cocoa rects 1.188 + // (NSRect) contain an origin (x,y) in a coordinate system with (0,0) 1.189 + // in the bottom-left of the primary screen. Both nsRect and NSRect 1.190 + // contain width/height info, with no difference in their use. 1.191 + // This function does no scaling, so the Gecko coordinates are 1.192 + // expected to be CSS pixels, which we treat as equal to Cocoa points. 1.193 + static NSRect GeckoRectToCocoaRect(const nsIntRect &geckoRect); 1.194 + 1.195 + // Converts aGeckoRect in dev pixels to points in Cocoa coordinates 1.196 + static NSRect GeckoRectToCocoaRectDevPix(const nsIntRect &aGeckoRect, 1.197 + CGFloat aBackingScale); 1.198 + 1.199 + // See explanation for geckoRectToCocoaRect, guess what this does... 1.200 + static nsIntRect CocoaRectToGeckoRect(const NSRect &cocoaRect); 1.201 + 1.202 + static nsIntRect CocoaRectToGeckoRectDevPix(const NSRect &aCocoaRect, 1.203 + CGFloat aBackingScale); 1.204 + 1.205 + // Gives the location for the event in screen coordinates. Do not call this 1.206 + // unless the window the event was originally targeted at is still alive! 1.207 + // anEvent may be nil -- in that case the current mouse location is returned. 1.208 + static NSPoint ScreenLocationForEvent(NSEvent* anEvent); 1.209 + 1.210 + // Determines if an event happened over a window, whether or not the event 1.211 + // is for the window. Does not take window z-order into account. 1.212 + static BOOL IsEventOverWindow(NSEvent* anEvent, NSWindow* aWindow); 1.213 + 1.214 + // Events are set up so that their coordinates refer to the window to which they 1.215 + // were originally sent. If we reroute the event somewhere else, we'll have 1.216 + // to get the window coordinates this way. Do not call this unless the window 1.217 + // the event was originally targeted at is still alive! 1.218 + static NSPoint EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow); 1.219 + 1.220 + static BOOL IsMomentumScrollEvent(NSEvent* aEvent); 1.221 + 1.222 + // Hides the Menu bar and the Dock. Multiple hide/show requests can be nested. 1.223 + static void HideOSChromeOnScreen(bool aShouldHide, NSScreen* aScreen); 1.224 + 1.225 + static nsIWidget* GetHiddenWindowWidget(); 1.226 + 1.227 + static void PrepareForNativeAppModalDialog(); 1.228 + static void CleanUpAfterNativeAppModalDialog(); 1.229 + 1.230 + // 3 utility functions to go from a frame of imgIContainer to CGImage and then to NSImage 1.231 + // Convert imgIContainer -> CGImageRef, caller owns result 1.232 + 1.233 + /** Creates a <code>CGImageRef</code> from a frame contained in an <code>imgIContainer</code>. 1.234 + Copies the pixel data from the indicated frame of the <code>imgIContainer</code> into a new <code>CGImageRef</code>. 1.235 + The caller owns the <code>CGImageRef</code>. 1.236 + @param aFrame the frame to convert 1.237 + @param aResult the resulting CGImageRef 1.238 + @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise 1.239 + */ 1.240 + static nsresult CreateCGImageFromSurface(SourceSurface* aSurface, 1.241 + CGImageRef* aResult); 1.242 + 1.243 + /** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>. 1.244 + Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>. 1.245 + The caller owns the <code>NSImage</code>. 1.246 + @param aInputImage the image to convert 1.247 + @param aResult the resulting NSImage 1.248 + @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise 1.249 + */ 1.250 + static nsresult CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult); 1.251 + 1.252 + /** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>. 1.253 + Combines the two methods above. The caller owns the <code>NSImage</code>. 1.254 + @param aImage the image to extract a frame from 1.255 + @param aWhichFrame the frame to extract (see imgIContainer FRAME_*) 1.256 + @param aResult the resulting NSImage 1.257 + @param scaleFactor the desired scale factor of the NSImage (2 for a retina display) 1.258 + @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise 1.259 + */ 1.260 + static nsresult CreateNSImageFromImageContainer(imgIContainer *aImage, uint32_t aWhichFrame, NSImage **aResult, CGFloat scaleFactor); 1.261 + 1.262 + /** 1.263 + * Returns nsAString for aSrc. 1.264 + */ 1.265 + static void GetStringForNSString(const NSString *aSrc, nsAString& aDist); 1.266 + 1.267 + /** 1.268 + * Makes NSString instance for aString. 1.269 + */ 1.270 + static NSString* ToNSString(const nsAString& aString); 1.271 + 1.272 + /** 1.273 + * Returns NSRect for aGeckoRect. 1.274 + * Just copies values between the two types; it does no coordinate-system 1.275 + * conversion, so both rects must have the same coordinate origin/direction. 1.276 + */ 1.277 + static void GeckoRectToNSRect(const nsIntRect& aGeckoRect, 1.278 + NSRect& aOutCocoaRect); 1.279 + 1.280 + /** 1.281 + * Returns Gecko rect for aCocoaRect. 1.282 + * Just copies values between the two types; it does no coordinate-system 1.283 + * conversion, so both rects must have the same coordinate origin/direction. 1.284 + */ 1.285 + static void NSRectToGeckoRect(const NSRect& aCocoaRect, 1.286 + nsIntRect& aOutGeckoRect); 1.287 + 1.288 + /** 1.289 + * Makes NSEvent instance for aEventTytpe and aEvent. 1.290 + */ 1.291 + static NSEvent* MakeNewCocoaEventWithType(NSEventType aEventType, 1.292 + NSEvent *aEvent); 1.293 + 1.294 + /** 1.295 + * Initializes aNPCocoaEvent. 1.296 + */ 1.297 + static void InitNPCocoaEvent(NPCocoaEvent* aNPCocoaEvent); 1.298 + 1.299 + /** 1.300 + * Initializes aPluginEvent for aCocoaEvent. 1.301 + */ 1.302 + static void InitPluginEvent(mozilla::WidgetPluginEvent &aPluginEvent, 1.303 + NPCocoaEvent &aCocoaEvent); 1.304 + /** 1.305 + * Initializes WidgetInputEvent for aNativeEvent or aModifiers. 1.306 + */ 1.307 + static void InitInputEvent(mozilla::WidgetInputEvent &aInputEvent, 1.308 + NSEvent* aNativeEvent); 1.309 + static void InitInputEvent(mozilla::WidgetInputEvent &aInputEvent, 1.310 + NSUInteger aModifiers); 1.311 + 1.312 + /** 1.313 + * ConvertToCarbonModifier() returns carbon modifier flags for the cocoa 1.314 + * modifier flags. 1.315 + * NOTE: The result never includes right*Key. 1.316 + */ 1.317 + static UInt32 ConvertToCarbonModifier(NSUInteger aCocoaModifier); 1.318 + 1.319 + /** 1.320 + * Whether to support HiDPI rendering. For testing purposes, to be removed 1.321 + * once we're comfortable with the HiDPI behavior. 1.322 + */ 1.323 + static bool HiDPIEnabled(); 1.324 + 1.325 + /** 1.326 + * Keys can optionally be bound by system or user key bindings to one or more 1.327 + * commands based on selectors. This collects any such commands in the 1.328 + * provided array. 1.329 + */ 1.330 + static void GetCommandsFromKeyEvent(NSEvent* aEvent, 1.331 + nsTArray<KeyBindingsCommand>& aCommands); 1.332 + 1.333 + /** 1.334 + * Converts the string name of a Gecko key (like "VK_HOME") to the 1.335 + * corresponding Cocoa Unicode character. 1.336 + */ 1.337 + static uint32_t ConvertGeckoNameToMacCharCode(const nsAString& aKeyCodeName); 1.338 + 1.339 + /** 1.340 + * Converts a Gecko key code (like NS_VK_HOME) to the corresponding Cocoa 1.341 + * Unicode character. 1.342 + */ 1.343 + static uint32_t ConvertGeckoKeyCodeToMacCharCode(uint32_t aKeyCode); 1.344 +}; 1.345 + 1.346 +#endif // nsCocoaUtils_h_