Bug 1851529 - Set clang-format ColumnLimit consistently. r=sylvestre,necko-reviewers,kershaw

For some reason, its value in the Google style we use is 80... except
for Objective-C, where it's 100, which led to things like:
https://hg.mozilla.org/mozilla-central/rev/31bf68247e6e
https://hg.mozilla.org/mozilla-central/rev/64ceb33533a4.

There's probably a discussion to have about whether 80 is the right
limit, but since it's what's used for everything except ObjC, let's roll
with it.

# ignore-this-changeset

Differential Revision: https://phabricator.services.mozilla.com/D187409
This commit is contained in:
Mike Hommey 2023-09-05 11:23:01 +00:00
Родитель ccc3244a24
Коммит 9331b9fb07
126 изменённых файлов: 8385 добавлений и 5412 удалений

Просмотреть файл

@ -1,4 +1,5 @@
BasedOnStyle: Google
ColumnLimit: 80
# Prevent the loss of indentation with these macros
MacroBlockBegin: "^\

Просмотреть файл

@ -24,27 +24,32 @@ using namespace mozilla::a11y;
// xpcAccessibleMacNSObjectWrapper
NS_IMPL_ISUPPORTS(xpcAccessibleMacNSObjectWrapper, nsIAccessibleMacNSObjectWrapper)
NS_IMPL_ISUPPORTS(xpcAccessibleMacNSObjectWrapper,
nsIAccessibleMacNSObjectWrapper)
xpcAccessibleMacNSObjectWrapper::xpcAccessibleMacNSObjectWrapper(id aNativeObj)
: mNativeObject(aNativeObj) {
[mNativeObject retain];
}
xpcAccessibleMacNSObjectWrapper::~xpcAccessibleMacNSObjectWrapper() { [mNativeObject release]; }
xpcAccessibleMacNSObjectWrapper::~xpcAccessibleMacNSObjectWrapper() {
[mNativeObject release];
}
id xpcAccessibleMacNSObjectWrapper::GetNativeObject() { return mNativeObject; }
// xpcAccessibleMacInterface
NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleMacInterface, xpcAccessibleMacNSObjectWrapper,
NS_IMPL_ISUPPORTS_INHERITED(xpcAccessibleMacInterface,
xpcAccessibleMacNSObjectWrapper,
nsIAccessibleMacInterface)
xpcAccessibleMacInterface::xpcAccessibleMacInterface(Accessible* aObj)
: xpcAccessibleMacNSObjectWrapper(GetNativeFromGeckoAccessible(aObj)) {}
NS_IMETHODIMP
xpcAccessibleMacInterface::GetAttributeNames(nsTArray<nsString>& aAttributeNames) {
xpcAccessibleMacInterface::GetAttributeNames(
nsTArray<nsString>& aAttributeNames) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN
if (!mNativeObject || [mNativeObject isExpired]) {
@ -63,14 +68,16 @@ xpcAccessibleMacInterface::GetAttributeNames(nsTArray<nsString>& aAttributeNames
}
NS_IMETHODIMP
xpcAccessibleMacInterface::GetParameterizedAttributeNames(nsTArray<nsString>& aAttributeNames) {
xpcAccessibleMacInterface::GetParameterizedAttributeNames(
nsTArray<nsString>& aAttributeNames) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN
if (!mNativeObject || [mNativeObject isExpired]) {
return NS_ERROR_NOT_AVAILABLE;
}
for (NSString* name in [mNativeObject accessibilityParameterizedAttributeNames]) {
for (NSString* name in
[mNativeObject accessibilityParameterizedAttributeNames]) {
nsAutoString attribName;
nsCocoaUtils::GetStringForNSString(name, attribName);
aAttributeNames.AppendElement(attribName);
@ -117,7 +124,8 @@ xpcAccessibleMacInterface::PerformAction(const nsAString& aActionName) {
}
NS_IMETHODIMP
xpcAccessibleMacInterface::GetAttributeValue(const nsAString& aAttributeName, JSContext* aCx,
xpcAccessibleMacInterface::GetAttributeValue(const nsAString& aAttributeName,
JSContext* aCx,
JS::MutableHandleValue aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN
@ -126,17 +134,20 @@ xpcAccessibleMacInterface::GetAttributeValue(const nsAString& aAttributeName, JS
}
NSString* attribName = nsCocoaUtils::ToNSString(aAttributeName);
return NSObjectToJsValue([mNativeObject accessibilityAttributeValue:attribName], aCx, aResult);
return NSObjectToJsValue(
[mNativeObject accessibilityAttributeValue:attribName], aCx, aResult);
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE)
}
NS_IMETHODIMP
xpcAccessibleMacInterface::IsAttributeSettable(const nsAString& aAttributeName, bool* aIsSettable) {
xpcAccessibleMacInterface::IsAttributeSettable(const nsAString& aAttributeName,
bool* aIsSettable) {
NS_ENSURE_ARG_POINTER(aIsSettable);
NSString* attribName = nsCocoaUtils::ToNSString(aAttributeName);
if ([mNativeObject respondsToSelector:@selector(accessibilityIsAttributeSettable:)]) {
if ([mNativeObject
respondsToSelector:@selector(accessibilityIsAttributeSettable:)]) {
*aIsSettable = [mNativeObject accessibilityIsAttributeSettable:attribName];
return NS_OK;
}
@ -146,13 +157,15 @@ xpcAccessibleMacInterface::IsAttributeSettable(const nsAString& aAttributeName,
NS_IMETHODIMP
xpcAccessibleMacInterface::SetAttributeValue(const nsAString& aAttributeName,
JS::HandleValue aAttributeValue, JSContext* aCx) {
JS::HandleValue aAttributeValue,
JSContext* aCx) {
nsresult rv = NS_OK;
id obj = JsValueToNSObject(aAttributeValue, aCx, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NSString* attribName = nsCocoaUtils::ToNSString(aAttributeName);
if ([mNativeObject respondsToSelector:@selector(accessibilitySetValue:forAttribute:)]) {
if ([mNativeObject respondsToSelector:@selector(accessibilitySetValue:
forAttribute:)]) {
// The NSObject has an attribute setter, call that.
[mNativeObject accessibilitySetValue:obj forAttribute:attribName];
return NS_OK;
@ -162,29 +175,30 @@ xpcAccessibleMacInterface::SetAttributeValue(const nsAString& aAttributeName,
}
NS_IMETHODIMP
xpcAccessibleMacInterface::GetParameterizedAttributeValue(const nsAString& aAttributeName,
JS::HandleValue aParameter,
JSContext* aCx,
JS::MutableHandleValue aResult) {
xpcAccessibleMacInterface::GetParameterizedAttributeValue(
const nsAString& aAttributeName, JS::HandleValue aParameter, JSContext* aCx,
JS::MutableHandleValue aResult) {
nsresult rv = NS_OK;
id paramObj = JsValueToNSObject(aParameter, aCx, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NSString* attribName = nsCocoaUtils::ToNSString(aAttributeName);
return NSObjectToJsValue(
[mNativeObject accessibilityAttributeValue:attribName forParameter:paramObj], aCx, aResult);
return NSObjectToJsValue([mNativeObject accessibilityAttributeValue:attribName
forParameter:paramObj],
aCx, aResult);
}
bool xpcAccessibleMacInterface::SupportsSelector(SEL aSelector) {
// return true if we have this selector, and if isAccessibilitySelectorAllowed
// is implemented too whether it is "allowed".
return [mNativeObject respondsToSelector:aSelector] &&
(![mNativeObject respondsToSelector:@selector(isAccessibilitySelectorAllowed:selector:)] ||
(![mNativeObject respondsToSelector:@selector
(isAccessibilitySelectorAllowed:selector:)] ||
[mNativeObject isAccessibilitySelectorAllowed:aSelector]);
}
nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
JS::MutableHandleValue aResult) {
nsresult xpcAccessibleMacInterface::NSObjectToJsValue(
id aObj, JSContext* aCx, JS::MutableHandleValue aResult) {
if (!aObj) {
aResult.set(JS::NullValue());
} else if ([aObj isKindOfClass:[NSString class]]) {
@ -201,7 +215,8 @@ nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
return NS_ERROR_FAILURE;
}
} else {
if (!mozilla::dom::ToJSValue(aCx, [(NSNumber*)aObj doubleValue], aResult)) {
if (!mozilla::dom::ToJSValue(aCx, [(NSNumber*)aObj doubleValue],
aResult)) {
return NS_ERROR_FAILURE;
}
}
@ -209,18 +224,25 @@ nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
strcmp([(NSValue*)aObj objCType], @encode(NSPoint)) == 0) {
NSPoint point = [(NSValue*)aObj pointValue];
return NSObjectToJsValue(
@[ [NSNumber numberWithDouble:point.x], [NSNumber numberWithDouble:point.y] ], aCx,
aResult);
@[
[NSNumber numberWithDouble:point.x],
[NSNumber numberWithDouble:point.y]
],
aCx, aResult);
} else if ([aObj isKindOfClass:[NSValue class]] &&
strcmp([(NSValue*)aObj objCType], @encode(NSSize)) == 0) {
NSSize size = [(NSValue*)aObj sizeValue];
return NSObjectToJsValue(
@[ [NSNumber numberWithDouble:size.width], [NSNumber numberWithDouble:size.height] ], aCx,
aResult);
@[
[NSNumber numberWithDouble:size.width],
[NSNumber numberWithDouble:size.height]
],
aCx, aResult);
} else if ([aObj isKindOfClass:[NSValue class]] &&
strcmp([(NSValue*)aObj objCType], @encode(NSRange)) == 0) {
NSRange range = [(NSValue*)aObj rangeValue];
return NSObjectToJsValue(@[ @(range.location), @(range.length) ], aCx, aResult);
return NSObjectToJsValue(@[ @(range.location), @(range.length) ], aCx,
aResult);
} else if ([aObj isKindOfClass:[NSValue class]] &&
strcmp([(NSValue*)aObj objCType], @encode(NSRect)) == 0) {
NSRect rect = [(NSValue*)aObj rectValue];
@ -263,14 +285,18 @@ nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
[attrStr
enumerateAttributesInRange:NSMakeRange(0, [attrStr length])
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
usingBlock:^(NSDictionary* attributes, NSRange range, BOOL* stop) {
NSString* str = [[attrStr string] substringWithRange:range];
options:
NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
usingBlock:^(NSDictionary* attributes, NSRange range,
BOOL* stop) {
NSString* str =
[[attrStr string] substringWithRange:range];
if (!str || !attributes) {
return;
}
NSMutableDictionary* attrRun = [attributes mutableCopy];
NSMutableDictionary* attrRun =
[attributes mutableCopy];
attrRun[@"string"] = str;
[attrRunArray addObject:attrRun];
@ -282,28 +308,34 @@ nsresult xpcAccessibleMacInterface::NSObjectToJsValue(id aObj, JSContext* aCx,
return NSObjectToJsValue(attrRunArray, aCx, aResult);
} else if (CFGetTypeID(aObj) == CGColorGetTypeID()) {
const CGFloat* components = CGColorGetComponents((CGColorRef)aObj);
NSString* hexString =
[NSString stringWithFormat:@"#%02x%02x%02x", (int)(components[0] * 0xff),
(int)(components[1] * 0xff), (int)(components[2] * 0xff)];
NSString* hexString = [NSString
stringWithFormat:@"#%02x%02x%02x", (int)(components[0] * 0xff),
(int)(components[1] * 0xff),
(int)(components[2] * 0xff)];
return NSObjectToJsValue(hexString, aCx, aResult);
} else if ([aObj respondsToSelector:@selector(isAccessibilityElement)]) {
// We expect all of our accessibility objects to implement isAccessibilityElement
// at the very least. If it is implemented we will assume its an accessibility object.
nsCOMPtr<nsIAccessibleMacInterface> obj = new xpcAccessibleMacInterface(aObj);
return nsContentUtils::WrapNative(aCx, obj, &NS_GET_IID(nsIAccessibleMacInterface), aResult);
// We expect all of our accessibility objects to implement
// isAccessibilityElement at the very least. If it is implemented we will
// assume its an accessibility object.
nsCOMPtr<nsIAccessibleMacInterface> obj =
new xpcAccessibleMacInterface(aObj);
return nsContentUtils::WrapNative(
aCx, obj, &NS_GET_IID(nsIAccessibleMacInterface), aResult);
} else {
// If this is any other kind of NSObject, just wrap it and return it.
// It will be opaque and immutable on the JS side, but it can be
// brought back to us in an argument.
nsCOMPtr<nsIAccessibleMacNSObjectWrapper> obj = new xpcAccessibleMacNSObjectWrapper(aObj);
return nsContentUtils::WrapNative(aCx, obj, &NS_GET_IID(nsIAccessibleMacNSObjectWrapper),
aResult);
nsCOMPtr<nsIAccessibleMacNSObjectWrapper> obj =
new xpcAccessibleMacNSObjectWrapper(aObj);
return nsContentUtils::WrapNative(
aCx, obj, &NS_GET_IID(nsIAccessibleMacNSObjectWrapper), aResult);
}
return NS_OK;
}
id xpcAccessibleMacInterface::JsValueToNSObject(JS::HandleValue aValue, JSContext* aCx,
id xpcAccessibleMacInterface::JsValueToNSObject(JS::HandleValue aValue,
JSContext* aCx,
nsresult* aResult) {
*aResult = NS_OK;
if (aValue.isInt32()) {
@ -363,9 +395,11 @@ id xpcAccessibleMacInterface::JsValueToNSObject(JS::HandleValue aValue, JSContex
nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
nsCOMPtr<nsIXPConnectWrappedNative> wrappedObj;
nsresult rv = xpc->GetWrappedNativeOfJSObject(aCx, obj, getter_AddRefs(wrappedObj));
nsresult rv =
xpc->GetWrappedNativeOfJSObject(aCx, obj, getter_AddRefs(wrappedObj));
NS_ENSURE_SUCCESS(rv, nil);
nsCOMPtr<nsIAccessibleMacNSObjectWrapper> macObjIface = do_QueryInterface(wrappedObj->Native());
nsCOMPtr<nsIAccessibleMacNSObjectWrapper> macObjIface =
do_QueryInterface(wrappedObj->Native());
return macObjIface->GetNativeObject();
}
@ -373,7 +407,8 @@ id xpcAccessibleMacInterface::JsValueToNSObject(JS::HandleValue aValue, JSContex
return nil;
}
id xpcAccessibleMacInterface::JsValueToNSValue(JS::HandleObject aObject, JSContext* aCx,
id xpcAccessibleMacInterface::JsValueToNSValue(JS::HandleObject aObject,
JSContext* aCx,
nsresult* aResult) {
*aResult = NS_ERROR_FAILURE;
JS::RootedValue valueTypeValue(aCx);
@ -421,14 +456,15 @@ id xpcAccessibleMacInterface::JsValueToNSValue(JS::HandleObject aObject, JSConte
}
*aResult = NS_OK;
return [NSValue valueWithRange:NSMakeRange(locationValue.toInt32(), lengthValue.toInt32())];
return [NSValue valueWithRange:NSMakeRange(locationValue.toInt32(),
lengthValue.toInt32())];
}
return nil;
}
id xpcAccessibleMacInterface::JsValueToSpecifiedNSObject(JS::HandleObject aObject, JSContext* aCx,
nsresult* aResult) {
id xpcAccessibleMacInterface::JsValueToSpecifiedNSObject(
JS::HandleObject aObject, JSContext* aCx, nsresult* aResult) {
*aResult = NS_ERROR_FAILURE;
JS::RootedValue objectTypeValue(aCx);
if (!JS_GetProperty(aCx, aObject, "objectType", &objectTypeValue)) {
@ -509,7 +545,8 @@ xpcAccessibleMacEvent::~xpcAccessibleMacEvent() {
NS_IMETHODIMP
xpcAccessibleMacEvent::GetMacIface(nsIAccessibleMacInterface** aMacIface) {
RefPtr<xpcAccessibleMacInterface> macIface = new xpcAccessibleMacInterface(mNativeObject);
RefPtr<xpcAccessibleMacInterface> macIface =
new xpcAccessibleMacInterface(mNativeObject);
macIface.forget(aMacIface);
return NS_OK;
}
@ -519,20 +556,25 @@ xpcAccessibleMacEvent::GetData(JSContext* aCx, JS::MutableHandleValue aData) {
return xpcAccessibleMacInterface::NSObjectToJsValue(mData, aCx, aData);
}
void xpcAccessibleMacEvent::FireEvent(id aNativeObj, id aNotification, id aUserInfo) {
if (nsCOMPtr<nsIObserverService> obsService = services::GetObserverService()) {
void xpcAccessibleMacEvent::FireEvent(id aNativeObj, id aNotification,
id aUserInfo) {
if (nsCOMPtr<nsIObserverService> obsService =
services::GetObserverService()) {
nsCOMPtr<nsISimpleEnumerator> observers;
// Get all observers for the mac event topic.
obsService->EnumerateObservers(NS_ACCESSIBLE_MAC_EVENT_TOPIC, getter_AddRefs(observers));
obsService->EnumerateObservers(NS_ACCESSIBLE_MAC_EVENT_TOPIC,
getter_AddRefs(observers));
if (observers) {
bool hasObservers = false;
observers->HasMoreElements(&hasObservers);
// If we have observers, notify them.
if (hasObservers) {
nsCOMPtr<nsIAccessibleMacEvent> xpcIface = new xpcAccessibleMacEvent(aNativeObj, aUserInfo);
nsCOMPtr<nsIAccessibleMacEvent> xpcIface =
new xpcAccessibleMacEvent(aNativeObj, aUserInfo);
nsAutoString notificationStr;
nsCocoaUtils::GetStringForNSString(aNotification, notificationStr);
obsService->NotifyObservers(xpcIface, NS_ACCESSIBLE_MAC_EVENT_TOPIC, notificationStr.get());
obsService->NotifyObservers(xpcIface, NS_ACCESSIBLE_MAC_EVENT_TOPIC,
notificationStr.get());
}
}
}

Просмотреть файл

@ -19,7 +19,8 @@ NS_IMPL_ISUPPORTS(nsKeychainMigrationUtils, nsIKeychainMigrationUtils)
NS_IMETHODIMP
nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
const nsACString& aAccountName, nsACString& aKey) {
const nsACString& aAccountName,
nsACString& aKey) {
// To retrieve a secret, we create a CFDictionary of the form:
// { class: generic password,
// service: the given service name
@ -31,9 +32,12 @@ nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
// matching the given service and account names. We then extract the data
// (i.e. the secret) and return it.
NSDictionary* searchDictionary = @{
(__bridge NSString*)kSecClass : (__bridge NSString*)kSecClassGenericPassword,
(__bridge NSString*)kSecAttrService : nsCocoaUtils::ToNSString(aServiceName),
(__bridge NSString*)kSecAttrAccount : nsCocoaUtils::ToNSString(aAccountName),
(__bridge NSString*)
kSecClass : (__bridge NSString*)kSecClassGenericPassword,
(__bridge NSString*)
kSecAttrService : nsCocoaUtils::ToNSString(aServiceName),
(__bridge NSString*)
kSecAttrAccount : nsCocoaUtils::ToNSString(aAccountName),
(__bridge NSString*)kSecMatchLimit : (__bridge NSString*)kSecMatchLimitOne,
(__bridge NSString*)kSecReturnAttributes : @YES,
(__bridge NSString*)kSecReturnData : @YES
@ -41,9 +45,11 @@ nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
CFTypeRef item;
// https://developer.apple.com/documentation/security/1398306-secitemcopymatching
OSStatus rv = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &item);
OSStatus rv =
SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &item);
if (rv != errSecSuccess) {
MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug, ("SecItemCopyMatching failed: %d", rv));
MOZ_LOG(gKeychainUtilsLog, LogLevel::Debug,
("SecItemCopyMatching failed: %d", rv));
return NS_ERROR_FAILURE;
}
NSDictionary* resultDict = [(__bridge NSDictionary*)item autorelease];
@ -53,8 +59,8 @@ nsKeychainMigrationUtils::GetGenericPassword(const nsACString& aServiceName,
return NS_ERROR_FAILURE;
}
if ([secret length] != 0) {
// We assume that the data is UTF-8 encoded since that seems to be common and
// Keychain Access shows it with that encoding.
// We assume that the data is UTF-8 encoded since that seems to be common
// and Keychain Access shows it with that encoding.
aKey.Assign(reinterpret_cast<const char*>([secret bytes]), [secret length]);
}

Просмотреть файл

@ -18,27 +18,31 @@ using namespace mozilla::widget;
static const int kSystemDefinedEventMediaKeysSubtype = 8;
static void SendFakeEvent(RefPtr<MediaHardwareKeysEventSourceMac>& aSource, int aKeyData) {
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeSystemDefined
location:NSZeroPoint
modifierFlags:0
timestamp:0
windowNumber:0
context:nil
subtype:kSystemDefinedEventMediaKeysSubtype
data1:aKeyData
data2:0];
aSource->EventTapCallback(nullptr, static_cast<CGEventType>(0), [event CGEvent], aSource.get());
static void SendFakeEvent(RefPtr<MediaHardwareKeysEventSourceMac>& aSource,
int aKeyData) {
NSEvent* event =
[NSEvent otherEventWithType:NSEventTypeSystemDefined
location:NSZeroPoint
modifierFlags:0
timestamp:0
windowNumber:0
context:nil
subtype:kSystemDefinedEventMediaKeysSubtype
data1:aKeyData
data2:0];
aSource->EventTapCallback(nullptr, static_cast<CGEventType>(0),
[event CGEvent], aSource.get());
}
static void NotifyFakeNonMediaKey(RefPtr<MediaHardwareKeysEventSourceMac>& aSource,
bool aIsKeyPressed) {
static void NotifyFakeNonMediaKey(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource, bool aIsKeyPressed) {
int keyData = 0 | ((aIsKeyPressed ? 0xA : 0xB) << 8);
SendFakeEvent(aSource, keyData);
}
static void NotifyFakeMediaControlKey(RefPtr<MediaHardwareKeysEventSourceMac>& aSource,
MediaControlKey aEvent, bool aIsKeyPressed) {
static void NotifyFakeMediaControlKey(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource, MediaControlKey aEvent,
bool aIsKeyPressed) {
int keyData = 0;
if (aEvent == MediaControlKey::Playpause) {
keyData = NX_KEYTYPE_PLAY << 16;
@ -51,27 +55,30 @@ static void NotifyFakeMediaControlKey(RefPtr<MediaHardwareKeysEventSourceMac>& a
SendFakeEvent(aSource, keyData);
}
static void NotifyKeyPressedMediaKey(RefPtr<MediaHardwareKeysEventSourceMac>& aSource,
MediaControlKey aEvent) {
static void NotifyKeyPressedMediaKey(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource, MediaControlKey aEvent) {
NotifyFakeMediaControlKey(aSource, aEvent, true /* key pressed */);
}
static void NotifyKeyReleasedMediaKeysEvent(RefPtr<MediaHardwareKeysEventSourceMac>& aSource,
MediaControlKey aEvent) {
static void NotifyKeyReleasedMediaKeysEvent(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource, MediaControlKey aEvent) {
NotifyFakeMediaControlKey(aSource, aEvent, false /* key released */);
}
static void NotifyKeyPressedNonMediaKeysEvents(RefPtr<MediaHardwareKeysEventSourceMac>& aSource) {
static void NotifyKeyPressedNonMediaKeysEvents(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource) {
NotifyFakeNonMediaKey(aSource, true /* key pressed */);
}
static void NotifyKeyReleasedNonMediaKeysEvents(RefPtr<MediaHardwareKeysEventSourceMac>& aSource) {
static void NotifyKeyReleasedNonMediaKeysEvents(
RefPtr<MediaHardwareKeysEventSourceMac>& aSource) {
NotifyFakeNonMediaKey(aSource, false /* key released */);
}
TEST(MediaHardwareKeysEventSourceMac, TestKeyPressedMediaKeysEvent)
{
RefPtr<MediaHardwareKeysEventSourceMac> source = new MediaHardwareKeysEventSourceMac();
RefPtr<MediaHardwareKeysEventSourceMac> source =
new MediaHardwareKeysEventSourceMac();
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
@ -94,7 +101,8 @@ TEST(MediaHardwareKeysEventSourceMac, TestKeyPressedMediaKeysEvent)
TEST(MediaHardwareKeysEventSourceMac, TestKeyReleasedMediaKeysEvent)
{
RefPtr<MediaHardwareKeysEventSourceMac> source = new MediaHardwareKeysEventSourceMac();
RefPtr<MediaHardwareKeysEventSourceMac> source =
new MediaHardwareKeysEventSourceMac();
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();
@ -117,7 +125,8 @@ TEST(MediaHardwareKeysEventSourceMac, TestKeyReleasedMediaKeysEvent)
TEST(MediaHardwareKeysEventSourceMac, TestNonMediaKeysEvent)
{
RefPtr<MediaHardwareKeysEventSourceMac> source = new MediaHardwareKeysEventSourceMac();
RefPtr<MediaHardwareKeysEventSourceMac> source =
new MediaHardwareKeysEventSourceMac();
ASSERT_TRUE(source->GetListenersNum() == 0);
RefPtr<MediaKeyListenerTest> listener = new MediaKeyListenerTest();

Просмотреть файл

@ -123,7 +123,8 @@ TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestMediaCenterPrevNextEvent)
ASSERT_TRUE(listener->IsResultEqualTo(MediaControlKey::Nexttrack));
MediaCenterEventHandler previousHandler = source->CreatePreviousTrackHandler();
MediaCenterEventHandler previousHandler =
source->CreatePreviousTrackHandler();
previousHandler(nil);
@ -153,9 +154,12 @@ TEST(MediaHardwareKeysEventSourceMacMediaCenter, TestSetMetadata)
// before checking the result.
PR_Sleep(PR_SecondsToInterval(1));
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyTitle] isEqualToString:@"MediaPlayback"]);
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyArtist] isEqualToString:@"Firefox"]);
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyAlbumTitle] isEqualToString:@"Mozilla"]);
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyTitle]
isEqualToString:@"MediaPlayback"]);
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyArtist]
isEqualToString:@"Firefox"]);
ASSERT_TRUE([center.nowPlayingInfo[MPMediaItemPropertyAlbumTitle]
isEqualToString:@"Mozilla"]);
source->Close();
PR_Sleep(PR_SecondsToInterval(1));

Просмотреть файл

@ -28,11 +28,13 @@ using namespace webrtc;
using namespace videocapturemodule;
static NSArray* camera_presets = @[
AVCaptureSessionPreset352x288, AVCaptureSessionPreset640x480, AVCaptureSessionPreset1280x720
AVCaptureSessionPreset352x288, AVCaptureSessionPreset640x480,
AVCaptureSessionPreset1280x720
];
#define IOS_UNSUPPORTED() \
RTC_LOG(LS_ERROR) << __FUNCTION__ << " is not supported on the iOS platform."; \
#define IOS_UNSUPPORTED() \
RTC_LOG(LS_ERROR) << __FUNCTION__ \
<< " is not supported on the iOS platform."; \
return -1;
VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() {
@ -60,7 +62,8 @@ int32_t DeviceInfoIos::Init() {
for (NSString* preset in camera_presets) {
BOOL support = [avDevice supportsAVCaptureSessionPreset:preset];
if (support) {
VideoCaptureCapability capability = [DeviceInfoIosObjC capabilityForPreset:preset];
VideoCaptureCapability capability =
[DeviceInfoIosObjC capabilityForPreset:preset];
capabilityVector.push_back(capability);
}
}
@ -73,31 +76,36 @@ int32_t DeviceInfoIos::Init() {
}
std::string deviceIdCopy(deviceId);
std::pair<std::string, VideoCaptureCapabilities> mapPair =
std::pair<std::string, VideoCaptureCapabilities>(deviceIdCopy, capabilityVector);
std::pair<std::string, VideoCaptureCapabilities>(deviceIdCopy,
capabilityVector);
_capabilitiesMap.insert(mapPair);
}
return 0;
}
uint32_t DeviceInfoIos::NumberOfDevices() { return [DeviceInfoIosObjC captureDeviceCount]; }
uint32_t DeviceInfoIos::NumberOfDevices() {
return [DeviceInfoIosObjC captureDeviceCount];
}
int32_t DeviceInfoIos::GetDeviceName(uint32_t deviceNumber, char* deviceNameUTF8,
uint32_t deviceNameUTF8Length, char* deviceUniqueIdUTF8,
uint32_t deviceUniqueIdUTF8Length, char* productUniqueIdUTF8,
uint32_t productUniqueIdUTF8Length, pid_t* pid) {
int32_t DeviceInfoIos::GetDeviceName(
uint32_t deviceNumber, char* deviceNameUTF8, uint32_t deviceNameUTF8Length,
char* deviceUniqueIdUTF8, uint32_t deviceUniqueIdUTF8Length,
char* productUniqueIdUTF8, uint32_t productUniqueIdUTF8Length, pid_t* pid) {
if (deviceNumber >= NumberOfDevices()) {
return -1;
}
NSString* deviceName = [DeviceInfoIosObjC deviceNameForIndex:deviceNumber];
NSString* deviceUniqueId = [DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber];
NSString* deviceUniqueId =
[DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber];
strncpy(deviceNameUTF8, [deviceName UTF8String], deviceNameUTF8Length);
deviceNameUTF8[deviceNameUTF8Length - 1] = '\0';
strncpy(deviceUniqueIdUTF8, deviceUniqueId.UTF8String, deviceUniqueIdUTF8Length);
strncpy(deviceUniqueIdUTF8, deviceUniqueId.UTF8String,
deviceUniqueIdUTF8Length);
deviceUniqueIdUTF8[deviceUniqueIdUTF8Length - 1] = '\0';
if (productUniqueIdUTF8) {
@ -140,14 +148,14 @@ int32_t DeviceInfoIos::GetCapability(const char* deviceUniqueIdUTF8,
return -1;
}
int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox(const char* deviceUniqueIdUTF8,
const char* dialogTitleUTF8,
void* parentWindow, uint32_t positionX,
uint32_t positionY) {
int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox(
const char* deviceUniqueIdUTF8, const char* dialogTitleUTF8,
void* parentWindow, uint32_t positionX, uint32_t positionY) {
IOS_UNSUPPORTED();
}
int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8, VideoRotation& orientation) {
int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8,
VideoRotation& orientation) {
if (strcmp(deviceUniqueIdUTF8, "Front Camera") == 0) {
orientation = kVideoRotation_0;
} else {

Просмотреть файл

@ -17,12 +17,14 @@
namespace webrtc::videocapturemodule {
/* static */
int32_t DeviceInfoAvFoundation::ConvertAVFrameRateToCapabilityFPS(Float64 aRate) {
int32_t DeviceInfoAvFoundation::ConvertAVFrameRateToCapabilityFPS(
Float64 aRate) {
return static_cast<int32_t>(aRate);
}
/* static */
webrtc::VideoType DeviceInfoAvFoundation::ConvertFourCCToVideoType(FourCharCode aCode) {
webrtc::VideoType DeviceInfoAvFoundation::ConvertFourCCToVideoType(
FourCharCode aCode) {
switch (aCode) {
case kCVPixelFormatType_420YpCbCr8Planar:
case kCVPixelFormatType_420YpCbCr8PlanarFullRange:
@ -57,11 +59,14 @@ webrtc::VideoType DeviceInfoAvFoundation::ConvertFourCCToVideoType(FourCharCode
}
DeviceInfoAvFoundation::DeviceInfoAvFoundation()
: mInvalidateCapabilities(false), mDeviceChangeCaptureInfo([[DeviceInfoIosObjC alloc] init]) {
: mInvalidateCapabilities(false),
mDeviceChangeCaptureInfo([[DeviceInfoIosObjC alloc] init]) {
[mDeviceChangeCaptureInfo registerOwner:this];
}
DeviceInfoAvFoundation::~DeviceInfoAvFoundation() { [mDeviceChangeCaptureInfo registerOwner:nil]; }
DeviceInfoAvFoundation::~DeviceInfoAvFoundation() {
[mDeviceChangeCaptureInfo registerOwner:nil];
}
void DeviceInfoAvFoundation::DeviceChange() {
mInvalidateCapabilities = true;
@ -74,12 +79,11 @@ uint32_t DeviceInfoAvFoundation::NumberOfDevices() {
return mDevicesAndCapabilities.size();
}
int32_t DeviceInfoAvFoundation::GetDeviceName(uint32_t aDeviceNumber, char* aDeviceNameUTF8,
uint32_t aDeviceNameLength, char* aDeviceUniqueIdUTF8,
uint32_t aDeviceUniqueIdUTF8Length,
char* /* aProductUniqueIdUTF8 */,
uint32_t /* aProductUniqueIdUTF8Length */,
pid_t* /* aPid */) {
int32_t DeviceInfoAvFoundation::GetDeviceName(
uint32_t aDeviceNumber, char* aDeviceNameUTF8, uint32_t aDeviceNameLength,
char* aDeviceUniqueIdUTF8, uint32_t aDeviceUniqueIdUTF8Length,
char* /* aProductUniqueIdUTF8 */, uint32_t /* aProductUniqueIdUTF8Length */,
pid_t* /* aPid */) {
RTC_DCHECK_RUN_ON(&mChecker);
// Don't EnsureCapabilitiesMap() here, since:
// 1) That might invalidate the capabilities map
@ -100,7 +104,8 @@ int32_t DeviceInfoAvFoundation::GetDeviceName(uint32_t aDeviceNumber, char* aDev
return 0;
}
int32_t DeviceInfoAvFoundation::NumberOfCapabilities(const char* aDeviceUniqueIdUTF8) {
int32_t DeviceInfoAvFoundation::NumberOfCapabilities(
const char* aDeviceUniqueIdUTF8) {
RTC_DCHECK_RUN_ON(&mChecker);
std::string deviceUniqueId(aDeviceUniqueIdUTF8);
@ -113,9 +118,9 @@ int32_t DeviceInfoAvFoundation::NumberOfCapabilities(const char* aDeviceUniqueId
return static_cast<int32_t>(capabilities.size());
}
int32_t DeviceInfoAvFoundation::GetCapability(const char* aDeviceUniqueIdUTF8,
const uint32_t aDeviceCapabilityNumber,
VideoCaptureCapability& aCapability) {
int32_t DeviceInfoAvFoundation::GetCapability(
const char* aDeviceUniqueIdUTF8, const uint32_t aDeviceCapabilityNumber,
VideoCaptureCapability& aCapability) {
RTC_DCHECK_RUN_ON(&mChecker);
std::string deviceUniqueId(aDeviceUniqueIdUTF8);
@ -133,7 +138,8 @@ int32_t DeviceInfoAvFoundation::GetCapability(const char* aDeviceUniqueIdUTF8,
return 0;
}
int32_t DeviceInfoAvFoundation::CreateCapabilityMap(const char* aDeviceUniqueIdUTF8) {
int32_t DeviceInfoAvFoundation::CreateCapabilityMap(
const char* aDeviceUniqueIdUTF8) {
RTC_DCHECK_RUN_ON(&mChecker);
const size_t deviceUniqueIdUTF8Length = strlen(aDeviceUniqueIdUTF8);
@ -141,7 +147,8 @@ int32_t DeviceInfoAvFoundation::CreateCapabilityMap(const char* aDeviceUniqueIdU
RTC_LOG(LS_INFO) << "Device name too long";
return -1;
}
RTC_LOG(LS_INFO) << "CreateCapabilityMap called for device " << aDeviceUniqueIdUTF8;
RTC_LOG(LS_INFO) << "CreateCapabilityMap called for device "
<< aDeviceUniqueIdUTF8;
std::string deviceUniqueId(aDeviceUniqueIdUTF8);
const auto* tup = FindDeviceAndCapabilities(deviceUniqueId);
if (!tup) {
@ -151,16 +158,18 @@ int32_t DeviceInfoAvFoundation::CreateCapabilityMap(const char* aDeviceUniqueIdU
// Store the new used device name
_lastUsedDeviceNameLength = deviceUniqueIdUTF8Length;
_lastUsedDeviceName =
static_cast<char*>(realloc(_lastUsedDeviceName, _lastUsedDeviceNameLength + 1));
memcpy(_lastUsedDeviceName, aDeviceUniqueIdUTF8, _lastUsedDeviceNameLength + 1);
_lastUsedDeviceName = static_cast<char*>(
realloc(_lastUsedDeviceName, _lastUsedDeviceNameLength + 1));
memcpy(_lastUsedDeviceName, aDeviceUniqueIdUTF8,
_lastUsedDeviceNameLength + 1);
const auto& [_, __, capabilities] = *tup;
_captureCapabilities = capabilities;
return static_cast<int32_t>(_captureCapabilities.size());
}
auto DeviceInfoAvFoundation::FindDeviceAndCapabilities(const std::string& aDeviceUniqueId) const
auto DeviceInfoAvFoundation::FindDeviceAndCapabilities(
const std::string& aDeviceUniqueId) const
-> const std::tuple<std::string, std::string, VideoCaptureCapabilities>* {
RTC_DCHECK_RUN_ON(&mChecker);
for (const auto& tup : mDevicesAndCapabilities) {
@ -185,13 +194,14 @@ void DeviceInfoAvFoundation::EnsureCapabilitiesMap() {
for (AVCaptureDevice* device in [RTCCameraVideoCapturer captureDevices]) {
std::string uniqueId = [NSString stdStringForString:device.uniqueID];
std::string name = [NSString stdStringForString:device.localizedName];
auto& [_, __, capabilities] =
mDevicesAndCapabilities.emplace_back(uniqueId, name, VideoCaptureCapabilities());
auto& [_, __, capabilities] = mDevicesAndCapabilities.emplace_back(
uniqueId, name, VideoCaptureCapabilities());
for (AVCaptureDeviceFormat* format in
[RTCCameraVideoCapturer supportedFormatsForDevice:device]) {
VideoCaptureCapability cap;
FourCharCode fourcc = CMFormatDescriptionGetMediaSubType(format.formatDescription);
FourCharCode fourcc =
CMFormatDescriptionGetMediaSubType(format.formatDescription);
cap.videoType = ConvertFourCCToVideoType(fourcc);
CMVideoDimensions dimensions =
CMVideoFormatDescriptionGetDimensions(format.formatDescription);

Просмотреть файл

@ -34,7 +34,8 @@
if (!_owner && owner) {
[self configureObservers];
} else if (_owner && !owner) {
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
NSNotificationCenter* notificationCenter =
[NSNotificationCenter defaultCenter];
for (id observer in _observers) {
[notificationCenter removeObserver:observer];
}
@ -47,7 +48,8 @@
+ (int)captureDeviceCount {
int cnt = 0;
@try {
for (AVCaptureDevice* device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
for (AVCaptureDevice* device in
[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([device isSuspended]) {
continue;
}
@ -62,7 +64,8 @@
+ (AVCaptureDevice*)captureDeviceForIndex:(int)index {
int cnt = 0;
@try {
for (AVCaptureDevice* device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
for (AVCaptureDevice* device in
[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([device isSuspended]) {
continue;
}
@ -79,7 +82,8 @@
}
+ (AVCaptureDevice*)captureDeviceForUniqueId:(NSString*)uniqueId {
for (AVCaptureDevice* device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
for (AVCaptureDevice* device in
[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([device isSuspended]) {
continue;
}
@ -133,34 +137,36 @@
- (void)configureObservers {
// register device connected / disconnected event
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
NSNotificationCenter* notificationCenter =
[NSNotificationCenter defaultCenter];
id deviceWasConnectedObserver =
[notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification* note) {
[_lock lock];
AVCaptureDevice* device = [note object];
BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo];
if (isVideoDevice && _owner) _owner->DeviceChange();
[_lock unlock];
}];
id deviceWasConnectedObserver = [notificationCenter
addObserverForName:AVCaptureDeviceWasConnectedNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification* note) {
[_lock lock];
AVCaptureDevice* device = [note object];
BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo];
if (isVideoDevice && _owner) _owner->DeviceChange();
[_lock unlock];
}];
id deviceWasDisconnectedObserver =
[notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification* note) {
[_lock lock];
AVCaptureDevice* device = [note object];
BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo];
if (isVideoDevice && _owner) _owner->DeviceChange();
[_lock unlock];
}];
id deviceWasDisconnectedObserver = [notificationCenter
addObserverForName:AVCaptureDeviceWasDisconnectedNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification* note) {
[_lock lock];
AVCaptureDevice* device = [note object];
BOOL isVideoDevice = [device hasMediaType:AVMediaTypeVideo];
if (isVideoDevice && _owner) _owner->DeviceChange();
[_lock unlock];
}];
_observers = [[NSArray alloc]
initWithObjects:deviceWasConnectedObserver, deviceWasDisconnectedObserver, nil];
_observers =
[[NSArray alloc] initWithObjects:deviceWasConnectedObserver,
deviceWasDisconnectedObserver, nil];
}
@end

Просмотреть файл

@ -57,18 +57,22 @@ using namespace webrtc::videocapturemodule;
}
// create and configure a new output (using callbacks)
AVCaptureVideoDataOutput* captureOutput = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureVideoDataOutput* captureOutput =
[[AVCaptureVideoDataOutput alloc] init];
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* val = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:val forKey:key];
NSNumber* val =
[NSNumber numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:val
forKey:key];
captureOutput.videoSettings = videoSettings;
// add new output
if ([_captureSession canAddOutput:captureOutput]) {
[_captureSession addOutput:captureOutput];
} else {
RTC_LOG(LS_ERROR) << __FUNCTION__ << ": Could not add output to AVCaptureSession";
RTC_LOG(LS_ERROR) << __FUNCTION__
<< ": Could not add output to AVCaptureSession";
}
#ifdef WEBRTC_IOS
@ -86,12 +90,14 @@ using namespace webrtc::videocapturemodule;
#endif
}
// Create a serial queue on which video capture will run. By setting the target,
// blocks should still run on DISPATH_QUEUE_PRIORITY_DEFAULT rather than creating
// a new thread.
_frameQueue = dispatch_queue_create("org.webrtc.videocapture", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(_frameQueue,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
// Create a serial queue on which video capture will run. By setting the
// target, blocks should still run on DISPATH_QUEUE_PRIORITY_DEFAULT rather
// than creating a new thread.
_frameQueue =
dispatch_queue_create("org.webrtc.videocapture", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(
_frameQueue,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
return self;
}
@ -144,11 +150,13 @@ using namespace webrtc::videocapturemodule;
if (capability.width > 1280 || capability.height > 720) {
return NO;
}
} else if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset640x480]) {
} else if ([_captureSession
canSetSessionPreset:AVCaptureSessionPreset640x480]) {
if (capability.width > 640 || capability.height > 480) {
return NO;
}
} else if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset352x288]) {
} else if ([_captureSession
canSetSessionPreset:AVCaptureSessionPreset352x288]) {
if (capability.width > 352 || capability.height > 288) {
return NO;
}
@ -175,8 +183,10 @@ using namespace webrtc::videocapturemodule;
return [[_captureSession outputs] firstObject];
}
- (void)startCaptureInBackgroundWithOutput:(AVCaptureVideoDataOutput*)currentOutput {
NSString* captureQuality = [NSString stringWithString:AVCaptureSessionPresetLow];
- (void)startCaptureInBackgroundWithOutput:
(AVCaptureVideoDataOutput*)currentOutput {
NSString* captureQuality =
[NSString stringWithString:AVCaptureSessionPresetLow];
if (_capability.width >= 1280 || _capability.height >= 720) {
captureQuality = [NSString stringWithString:AVCaptureSessionPreset1280x720];
} else if (_capability.width >= 640 || _capability.height >= 480) {
@ -214,7 +224,8 @@ using namespace webrtc::videocapturemodule;
_connection.videoOrientation = AVCaptureVideoOrientationPortrait;
break;
case UIDeviceOrientationPortraitUpsideDown:
_connection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
_connection.videoOrientation =
AVCaptureVideoOrientationPortraitUpsideDown;
break;
case UIDeviceOrientationLandscapeLeft:
_connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
@ -236,7 +247,8 @@ using namespace webrtc::videocapturemodule;
- (void)onVideoError:(NSNotification*)notification {
NSLog(@"onVideoError: %@", notification);
// TODO(sjlee): make the specific error handling with this notification.
RTC_LOG(LS_ERROR) << __FUNCTION__ << ": [AVCaptureSession startRunning] error.";
RTC_LOG(LS_ERROR) << __FUNCTION__
<< ": [AVCaptureSession startRunning] error.";
}
- (BOOL)stopCapture {
@ -265,7 +277,8 @@ using namespace webrtc::videocapturemodule;
NSArray* currentInputs = [_captureSession inputs];
// remove current input
if ([currentInputs count] > 0) {
AVCaptureInput* currentInput = (AVCaptureInput*)[currentInputs objectAtIndex:0];
AVCaptureInput* currentInput =
(AVCaptureInput*)[currentInputs objectAtIndex:0];
[_captureSession removeInput:currentInput];
}
@ -277,7 +290,8 @@ using namespace webrtc::videocapturemodule;
return NO;
}
AVCaptureDevice* captureDevice = [DeviceInfoIosObjC captureDeviceForUniqueId:uniqueId];
AVCaptureDevice* captureDevice =
[DeviceInfoIosObjC captureDeviceForUniqueId:uniqueId];
if (!captureDevice) {
return NO;
@ -285,13 +299,15 @@ using namespace webrtc::videocapturemodule;
// now create capture session input out of AVCaptureDevice
NSError* deviceError = nil;
AVCaptureDeviceInput* newCaptureInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice
error:&deviceError];
AVCaptureDeviceInput* newCaptureInput =
[AVCaptureDeviceInput deviceInputWithDevice:captureDevice
error:&deviceError];
if (!newCaptureInput) {
const char* errorMessage = [[deviceError localizedDescription] UTF8String];
RTC_LOG(LS_ERROR) << __FUNCTION__ << ": deviceInputWithDevice error:" << errorMessage;
RTC_LOG(LS_ERROR) << __FUNCTION__
<< ": deviceInputWithDevice error:" << errorMessage;
return NO;
}

Просмотреть файл

@ -23,7 +23,8 @@ using namespace mozilla;
using namespace webrtc;
using namespace videocapturemodule;
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create(const char* deviceUniqueIdUTF8) {
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create(
const char* deviceUniqueIdUTF8) {
if (StaticPrefs::media_getusermedia_camera_macavf_enabled_AtStartup()) {
return VideoCaptureAvFoundation::Create(deviceUniqueIdUTF8);
}
@ -44,12 +45,14 @@ VideoCaptureIos::~VideoCaptureIos() {
}
}
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureIos::Create(const char* deviceUniqueIdUTF8) {
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureIos::Create(
const char* deviceUniqueIdUTF8) {
if (!deviceUniqueIdUTF8[0]) {
return NULL;
}
rtc::scoped_refptr<VideoCaptureIos> capture_module(new rtc::RefCountedObject<VideoCaptureIos>());
rtc::scoped_refptr<VideoCaptureIos> capture_module(
new rtc::RefCountedObject<VideoCaptureIos>());
const int32_t name_length = strlen(deviceUniqueIdUTF8);
if (name_length >= kVideoCaptureUniqueNameLength) return nullptr;
@ -65,14 +68,16 @@ rtc::scoped_refptr<VideoCaptureModule> VideoCaptureIos::Create(const char* devic
}
if (![capture_module->capture_device_
setCaptureDeviceByUniqueId:[[NSString alloc] initWithCString:deviceUniqueIdUTF8
encoding:NSUTF8StringEncoding]]) {
setCaptureDeviceByUniqueId:
[[NSString alloc] initWithCString:deviceUniqueIdUTF8
encoding:NSUTF8StringEncoding]]) {
return nullptr;
}
return capture_module;
}
int32_t VideoCaptureIos::StartCapture(const VideoCaptureCapability& capability) {
int32_t VideoCaptureIos::StartCapture(
const VideoCaptureCapability& capability) {
capability_ = capability;
if (![capture_device_ startCaptureWithCapability:capability]) {

Просмотреть файл

@ -38,30 +38,37 @@ webrtc::VideoRotation ToNativeRotation(RTCVideoRotation aRotation) {
case RTCVideoRotation_270:
return webrtc::kVideoRotation_270;
default:
MOZ_CRASH_UNSAFE_PRINTF("Unexpected rotation %d", static_cast<int>(aRotation));
MOZ_CRASH_UNSAFE_PRINTF("Unexpected rotation %d",
static_cast<int>(aRotation));
return webrtc::kVideoRotation_0;
}
}
AVCaptureDeviceFormat* _Nullable FindFormat(AVCaptureDevice* _Nonnull aDevice,
webrtc::VideoCaptureCapability aCapability) {
AVCaptureDeviceFormat* _Nullable FindFormat(
AVCaptureDevice* _Nonnull aDevice,
webrtc::VideoCaptureCapability aCapability) {
for (AVCaptureDeviceFormat* format in [aDevice formats]) {
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
CMVideoDimensions dimensions =
CMVideoFormatDescriptionGetDimensions(format.formatDescription);
if (dimensions.width != aCapability.width) {
continue;
}
if (dimensions.height != aCapability.height) {
continue;
}
FourCharCode fourcc = CMFormatDescriptionGetMediaSubType(format.formatDescription);
if (aCapability.videoType != DeviceInfoAvFoundation::ConvertFourCCToVideoType(fourcc)) {
FourCharCode fourcc =
CMFormatDescriptionGetMediaSubType(format.formatDescription);
if (aCapability.videoType !=
DeviceInfoAvFoundation::ConvertFourCCToVideoType(fourcc)) {
continue;
}
if ([format.videoSupportedFrameRateRanges
indexOfObjectPassingTest:^BOOL(AVFrameRateRange* _Nonnull obj, NSUInteger idx,
indexOfObjectPassingTest:^BOOL(AVFrameRateRange* _Nonnull obj,
NSUInteger idx,
BOOL* _Nonnull stop) {
return static_cast<BOOL>(DeviceInfoAvFoundation::ConvertAVFrameRateToCapabilityFPS(
obj.maxFrameRate) == aCapability.maxFPS);
return static_cast<BOOL>(
DeviceInfoAvFoundation::ConvertAVFrameRateToCapabilityFPS(
obj.maxFrameRate) == aCapability.maxFPS);
}] == NSNotFound) {
continue;
}
@ -73,7 +80,8 @@ AVCaptureDeviceFormat* _Nullable FindFormat(AVCaptureDevice* _Nonnull aDevice,
} // namespace
@implementation VideoCaptureAdapter
- (void)setCapturer:(webrtc::videocapturemodule::VideoCaptureAvFoundation* _Nullable)capturer {
- (void)setCapturer:
(webrtc::videocapturemodule::VideoCaptureAvFoundation* _Nullable)capturer {
webrtc::MutexLock lock(&_mutex);
_capturer = capturer;
}
@ -91,10 +99,12 @@ AVCaptureDeviceFormat* _Nullable FindFormat(AVCaptureDevice* _Nonnull aDevice,
@end
namespace webrtc::videocapturemodule {
VideoCaptureAvFoundation::VideoCaptureAvFoundation(AVCaptureDevice* _Nonnull aDevice)
VideoCaptureAvFoundation::VideoCaptureAvFoundation(
AVCaptureDevice* _Nonnull aDevice)
: mDevice(aDevice),
mAdapter([[VideoCaptureAdapter alloc] init]),
mCapturer([[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc] initWithDelegate:mAdapter]),
mCapturer([[RTC_OBJC_TYPE(RTCCameraVideoCapturer) alloc]
initWithDelegate:mAdapter]),
mCallbackThreadId() {
const char* uniqueId = [[aDevice uniqueID] UTF8String];
size_t len = strlen(uniqueId);
@ -123,7 +133,8 @@ rtc::scoped_refptr<VideoCaptureModule> VideoCaptureAvFoundation::Create(
return nullptr;
}
int32_t VideoCaptureAvFoundation::StartCapture(const VideoCaptureCapability& aCapability) {
int32_t VideoCaptureAvFoundation::StartCapture(
const VideoCaptureCapability& aCapability) {
RTC_DCHECK_RUN_ON(&mChecker);
AVCaptureDeviceFormat* format = FindFormat(mDevice, aCapability);
if (!format) {
@ -133,7 +144,8 @@ int32_t VideoCaptureAvFoundation::StartCapture(const VideoCaptureCapability& aCa
{
MutexLock lock(&api_lock_);
if (mCapability) {
if (mCapability->width == aCapability.width && mCapability->height == aCapability.height &&
if (mCapability->width == aCapability.width &&
mCapability->height == aCapability.height &&
mCapability->maxFPS == aCapability.maxFPS &&
mCapability->videoType == aCapability.videoType) {
return 0;
@ -250,28 +262,33 @@ bool VideoCaptureAvFoundation::CaptureStarted() {
return mCapability.isSome();
}
int32_t VideoCaptureAvFoundation::CaptureSettings(VideoCaptureCapability& aSettings) {
int32_t VideoCaptureAvFoundation::CaptureSettings(
VideoCaptureCapability& aSettings) {
MOZ_CRASH("Unexpected call");
return -1;
}
int32_t VideoCaptureAvFoundation::OnFrame(__strong RTCVideoFrame* _Nonnull aFrame) {
int32_t VideoCaptureAvFoundation::OnFrame(
__strong RTCVideoFrame* _Nonnull aFrame) {
MaybeRegisterCallbackThread();
if (MutexLock lock(&api_lock_); MOZ_LIKELY(mTrackingId)) {
mCaptureRecorder.Start(0, "VideoCaptureAVFoundation"_ns, *mTrackingId, aFrame.width,
aFrame.height, mImageType.valueOr(CaptureStage::ImageType::Unknown));
mCaptureRecorder.Start(
0, "VideoCaptureAVFoundation"_ns, *mTrackingId, aFrame.width,
aFrame.height, mImageType.valueOr(CaptureStage::ImageType::Unknown));
if (mCapability && mCapability->videoType != webrtc::VideoType::kI420) {
mConversionRecorder.Start(0, "VideoCaptureAVFoundation"_ns, *mTrackingId, aFrame.width,
aFrame.height);
mConversionRecorder.Start(0, "VideoCaptureAVFoundation"_ns, *mTrackingId,
aFrame.width, aFrame.height);
}
}
const int64_t timestamp_us = aFrame.timeStampNs / rtc::kNumNanosecsPerMicrosec;
const int64_t timestamp_us =
aFrame.timeStampNs / rtc::kNumNanosecsPerMicrosec;
RTCI420Buffer* buffer = [aFrame.buffer toI420];
mConversionRecorder.Record(0);
// Accessing the (intended-to-be-private) native buffer directly is hacky but lets us skip two
// copies
rtc::scoped_refptr<webrtc::I420BufferInterface> nativeBuffer = buffer.nativeI420Buffer;
// Accessing the (intended-to-be-private) native buffer directly is hacky but
// lets us skip two copies
rtc::scoped_refptr<webrtc::I420BufferInterface> nativeBuffer =
buffer.nativeI420Buffer;
auto frame = webrtc::VideoFrame::Builder()
.set_video_frame_buffer(nativeBuffer)
.set_rotation(ToNativeRotation(aFrame.rotation))
@ -288,8 +305,8 @@ void VideoCaptureAvFoundation::SetTrackingId(uint32_t aTrackingIdProcId) {
RTC_DCHECK_RUN_ON(&mChecker);
MutexLock lock(&api_lock_);
if (NS_WARN_IF(mTrackingId.isSome())) {
// This capture instance must be shared across multiple camera requests. For now ignore other
// requests than the first.
// This capture instance must be shared across multiple camera requests. For
// now ignore other requests than the first.
return;
}
mTrackingId.emplace(TrackingId::Source::Camera, aTrackingIdProcId);
@ -301,6 +318,7 @@ void VideoCaptureAvFoundation::MaybeRegisterCallbackThread() {
return;
}
mCallbackThreadId = id;
CallbackThreadRegistry::Get()->Register(mCallbackThreadId, "VideoCaptureAVFoundationCallback");
CallbackThreadRegistry::Get()->Register(mCallbackThreadId,
"VideoCaptureAVFoundationCallback");
}
} // namespace webrtc::videocapturemodule

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset:
* 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -37,7 +38,8 @@ class SpeechTaskCallback final : public nsISpeechTaskCallback {
const nsTArray<size_t>& aOffsets);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(SpeechTaskCallback, nsISpeechTaskCallback)
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(SpeechTaskCallback,
nsISpeechTaskCallback)
NS_DECL_NSISPEECHTASKCALLBACK
@ -79,7 +81,8 @@ class SpeechTaskCallback final : public nsISpeechTaskCallback {
mCallback->OnWillSpeakWord(aRange.location, aRange.length);
}
- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender didFinishSpeaking:(BOOL)aFinishedSpeaking {
- (void)speechSynthesizer:(NSSpeechSynthesizer*)aSender
didFinishSpeaking:(BOOL)aFinishedSpeaking {
mCallback->OnDidFinishSpeaking();
}
@ -101,9 +104,13 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechTaskCallback)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechTaskCallback)
SpeechTaskCallback::SpeechTaskCallback(nsISpeechTask* aTask, NSSpeechSynthesizer* aSynth,
SpeechTaskCallback::SpeechTaskCallback(nsISpeechTask* aTask,
NSSpeechSynthesizer* aSynth,
const nsTArray<size_t>& aOffsets)
: mTask(aTask), mSpeechSynthesizer(aSynth), mCurrentIndex(0), mOffsets(aOffsets.Clone()) {
: mTask(aTask),
mSpeechSynthesizer(aSynth),
mCurrentIndex(0),
mOffsets(aOffsets.Clone()) {
mDelegate = [[SpeechDelegate alloc] initWithCallback:this];
[mSpeechSynthesizer setDelegate:mDelegate];
mStartingTime = TimeStamp::Now();
@ -179,7 +186,8 @@ void SpeechTaskCallback::OnWillSpeakWord(uint32_t aIndex, uint32_t aLength) {
if (!mTask) {
return;
}
mTask->DispatchBoundary(u"word"_ns, GetTimeDurationFromStart(), mCurrentIndex, aLength, 1);
mTask->DispatchBoundary(u"word"_ns, GetTimeDurationFromStart(), mCurrentIndex,
aLength, 1);
}
void SpeechTaskCallback::OnError(uint32_t aIndex) {
@ -210,8 +218,11 @@ struct OSXVoice {
class RegisterVoicesRunnable final : public Runnable {
public:
RegisterVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService, nsTArray<OSXVoice>& aList)
: Runnable("RegisterVoicesRunnable"), mSpeechService(aSpeechService), mVoices(aList) {}
RegisterVoicesRunnable(OSXSpeechSynthesizerService* aSpeechService,
nsTArray<OSXVoice>& aList)
: Runnable("RegisterVoicesRunnable"),
mSpeechService(aSpeechService),
mVoices(aList) {}
NS_IMETHOD Run() override;
@ -226,13 +237,15 @@ class RegisterVoicesRunnable final : public Runnable {
NS_IMETHODIMP
RegisterVoicesRunnable::Run() {
nsresult rv;
nsCOMPtr<nsISynthVoiceRegistry> registry = do_GetService(NS_SYNTHVOICEREGISTRY_CONTRACTID, &rv);
nsCOMPtr<nsISynthVoiceRegistry> registry =
do_GetService(NS_SYNTHVOICEREGISTRY_CONTRACTID, &rv);
if (!registry) {
return rv;
}
for (OSXVoice voice : mVoices) {
rv = registry->AddVoice(mSpeechService, voice.mUri, voice.mName, voice.mLocale, true, false);
rv = registry->AddVoice(mSpeechService, voice.mUri, voice.mName,
voice.mLocale, true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
@ -275,11 +288,14 @@ EnumVoicesRunnable::Run() {
NSDictionary* attr = [NSSpeechSynthesizer attributesForVoice:voice];
nsAutoString identifier;
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceIdentifier], identifier);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceIdentifier],
identifier);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceName], item.mName);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceName],
item.mName);
nsCocoaUtils::GetStringForNSString([attr objectForKey:NSVoiceLocaleIdentifier], item.mLocale);
nsCocoaUtils::GetStringForNSString(
[attr objectForKey:NSVoiceLocaleIdentifier], item.mLocale);
item.mLocale.ReplaceChar('_', '-');
item.mUri.AssignLiteral("urn:moz-tts:osx:");
@ -292,16 +308,19 @@ EnumVoicesRunnable::Run() {
list.AppendElement(item);
}
RefPtr<RegisterVoicesRunnable> runnable = new RegisterVoicesRunnable(mSpeechService, list);
RefPtr<RegisterVoicesRunnable> runnable =
new RegisterVoicesRunnable(mSpeechService, list);
NS_DispatchAndSpinEventLoopUntilComplete("EnumVoicesRunnable"_ns,
GetMainThreadSerialEventTarget(), runnable.forget());
GetMainThreadSerialEventTarget(),
runnable.forget());
return NS_OK;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
StaticRefPtr<OSXSpeechSynthesizerService> OSXSpeechSynthesizerService::sSingleton;
StaticRefPtr<OSXSpeechSynthesizerService>
OSXSpeechSynthesizerService::sSingleton;
NS_INTERFACE_MAP_BEGIN(OSXSpeechSynthesizerService)
NS_INTERFACE_MAP_ENTRY(nsISpeechService)
@ -312,7 +331,8 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(OSXSpeechSynthesizerService)
NS_IMPL_RELEASE(OSXSpeechSynthesizerService)
OSXSpeechSynthesizerService::OSXSpeechSynthesizerService() : mInitialized(false) {}
OSXSpeechSynthesizerService::OSXSpeechSynthesizerService()
: mInitialized(false) {}
bool OSXSpeechSynthesizerService::Init() {
if (Preferences::GetBool("media.webspeech.synth.test") ||
@ -335,8 +355,10 @@ bool OSXSpeechSynthesizerService::Init() {
}
NS_IMETHODIMP
OSXSpeechSynthesizerService::Speak(const nsAString& aText, const nsAString& aUri, float aVolume,
float aRate, float aPitch, nsISpeechTask* aTask) {
OSXSpeechSynthesizerService::Speak(const nsAString& aText,
const nsAString& aUri, float aVolume,
float aRate, float aPitch,
nsISpeechTask* aTask) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_ASSERT(StringBeginsWith(aUri, u"urn:moz-tts:osx:"_ns),
@ -348,11 +370,16 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText, const nsAString& aUri
[synth setVoice:identifier];
// default rate is 180-220
[synth setObject:[NSNumber numberWithInt:aRate * 200] forProperty:NSSpeechRateProperty error:nil];
[synth setObject:[NSNumber numberWithInt:aRate * 200]
forProperty:NSSpeechRateProperty
error:nil];
// volume allows 0.0-1.0
[synth setObject:[NSNumber numberWithFloat:aVolume] forProperty:NSSpeechVolumeProperty error:nil];
[synth setObject:[NSNumber numberWithFloat:aVolume]
forProperty:NSSpeechVolumeProperty
error:nil];
// Use default pitch value to calculate this
NSNumber* defaultPitch = [synth objectForProperty:NSSpeechPitchBaseProperty error:nil];
NSNumber* defaultPitch = [synth objectForProperty:NSSpeechPitchBaseProperty
error:nil];
if (defaultPitch) {
int newPitch = [defaultPitch intValue] * (aPitch / 2 + 0.5);
[synth setObject:[NSNumber numberWithInt:newPitch]
@ -370,8 +397,8 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText, const nsAString& aUri
// This loop looks for occurances of "[[" or "]]", escapes them, and
// populates the offsets array to supply a map to the original offsets.
for (size_t i = 0; i < aText.Length(); i++) {
if (aText.Length() > i + 1 &&
((aText[i] == ']' && aText[i + 1] == ']') || (aText[i] == '[' && aText[i + 1] == '['))) {
if (aText.Length() > i + 1 && ((aText[i] == ']' && aText[i + 1] == ']') ||
(aText[i] == '[' && aText[i + 1] == '['))) {
escapedText.AppendLiteral(DLIM_ESCAPE_START);
offsets.AppendElements(strlen(DLIM_ESCAPE_START));
escapedText.Append(aText[i]);
@ -386,7 +413,8 @@ OSXSpeechSynthesizerService::Speak(const nsAString& aText, const nsAString& aUri
}
}
RefPtr<SpeechTaskCallback> callback = new SpeechTaskCallback(aTask, synth, offsets);
RefPtr<SpeechTaskCallback> callback =
new SpeechTaskCallback(aTask, synth, offsets);
nsresult rv = aTask->Setup(callback);
NS_ENSURE_SUCCESS(rv, rv);
@ -413,7 +441,8 @@ OSXSpeechSynthesizerService* OSXSpeechSynthesizerService::GetInstance() {
}
if (!sSingleton) {
RefPtr<OSXSpeechSynthesizerService> speechService = new OSXSpeechSynthesizerService();
RefPtr<OSXSpeechSynthesizerService> speechService =
new OSXSpeechSynthesizerService();
if (speechService->Init()) {
sSingleton = speechService;
ClearOnShutdown(&sSingleton);
@ -422,7 +451,8 @@ OSXSpeechSynthesizerService* OSXSpeechSynthesizerService::GetInstance() {
return sSingleton;
}
already_AddRefed<OSXSpeechSynthesizerService> OSXSpeechSynthesizerService::GetInstanceForService() {
already_AddRefed<OSXSpeechSynthesizerService>
OSXSpeechSynthesizerService::GetInstanceForService() {
RefPtr<OSXSpeechSynthesizerService> speechService = GetInstance();
return speechService.forget();
}

Просмотреть файл

@ -29,15 +29,18 @@
using namespace mozilla;
static const CLLocationAccuracy kHIGH_ACCURACY = kCLLocationAccuracyBest;
static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTenMeters;
static const CLLocationAccuracy kDEFAULT_ACCURACY =
kCLLocationAccuracyNearestTenMeters;
@interface LocationDelegate : NSObject <CLLocationManagerDelegate> {
CoreLocationLocationProvider* mProvider;
}
- (id)init:(CoreLocationLocationProvider*)aProvider;
- (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)aError;
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)locations;
- (void)locationManager:(CLLocationManager*)aManager
didFailWithError:(NSError*)aError;
- (void)locationManager:(CLLocationManager*)aManager
didUpdateLocations:(NSArray*)locations;
@end
@ -50,28 +53,32 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
return self;
}
- (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)aError {
nsCOMPtr<nsIConsoleService> console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
- (void)locationManager:(CLLocationManager*)aManager
didFailWithError:(NSError*)aError {
nsCOMPtr<nsIConsoleService> console =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
NS_ENSURE_TRUE_VOID(console);
NSString* message =
[@"Failed to acquire position: " stringByAppendingString:[aError localizedDescription]];
NSString* message = [@"Failed to acquire position: "
stringByAppendingString:[aError localizedDescription]];
console->LogStringMessage(NS_ConvertUTF8toUTF16([message UTF8String]).get());
if ([aError code] == kCLErrorDenied) {
mProvider->NotifyError(dom::GeolocationPositionError_Binding::PERMISSION_DENIED);
mProvider->NotifyError(
dom::GeolocationPositionError_Binding::PERMISSION_DENIED);
return;
}
// The CL provider does not fallback to GeoIP, so use NetworkGeolocationProvider for this.
// The concept here is: on error, hand off geolocation to MLS, which will then report
// back a location or error.
// The CL provider does not fallback to GeoIP, so use
// NetworkGeolocationProvider for this. The concept here is: on error, hand
// off geolocation to MLS, which will then report back a location or error.
mProvider->CreateMLSFallbackProvider();
}
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations {
- (void)locationManager:(CLLocationManager*)aManager
didUpdateLocations:(NSArray*)aLocations {
if (aLocations.count < 1) {
return;
}
@ -92,24 +99,29 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
altitudeAccuracy = UnspecifiedNaN<double>();
}
double speed = location.speed >= 0 ? location.speed : UnspecifiedNaN<double>();
double speed =
location.speed >= 0 ? location.speed : UnspecifiedNaN<double>();
double heading = location.course >= 0 ? location.course : UnspecifiedNaN<double>();
double heading =
location.course >= 0 ? location.course : UnspecifiedNaN<double>();
// nsGeoPositionCoords will convert NaNs to null for optional properties of
// the JavaScript Coordinates object.
nsCOMPtr<nsIDOMGeoPosition> geoPosition = new nsGeoPosition(
location.coordinate.latitude, location.coordinate.longitude, altitude,
location.horizontalAccuracy, altitudeAccuracy, heading, speed, PR_Now() / PR_USEC_PER_MSEC);
location.horizontalAccuracy, altitudeAccuracy, heading, speed,
PR_Now() / PR_USEC_PER_MSEC);
mProvider->Update(geoPosition);
Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, false);
}
@end
NS_IMPL_ISUPPORTS(CoreLocationLocationProvider::MLSUpdate, nsIGeolocationUpdate);
NS_IMPL_ISUPPORTS(CoreLocationLocationProvider::MLSUpdate,
nsIGeolocationUpdate);
CoreLocationLocationProvider::MLSUpdate::MLSUpdate(CoreLocationLocationProvider& parentProvider)
CoreLocationLocationProvider::MLSUpdate::MLSUpdate(
CoreLocationLocationProvider& parentProvider)
: mParentLocationProvider(parentProvider) {}
NS_IMETHODIMP
@ -175,7 +187,8 @@ CoreLocationLocationProvider::Startup() {
mCLObjects = clObjs.release();
}
// Must be stopped before starting or response (success or failure) is not guaranteed
// Must be stopped before starting or response (success or failure) is not
// guaranteed
[mCLObjects->mLocationManager stopUpdatingLocation];
[mCLObjects->mLocationManager startUpdatingLocation];
return NS_OK;
@ -212,7 +225,8 @@ NS_IMETHODIMP
CoreLocationLocationProvider::SetHighAccuracy(bool aEnable) {
NS_ENSURE_STATE(mCLObjects);
mCLObjects->mLocationManager.desiredAccuracy = (aEnable ? kHIGH_ACCURACY : kDEFAULT_ACCURACY);
mCLObjects->mLocationManager.desiredAccuracy =
(aEnable ? kHIGH_ACCURACY : kDEFAULT_ACCURACY);
return NS_OK;
}

Просмотреть файл

@ -32,7 +32,8 @@ nsOSPermissionRequest::GetScreenCapturePermissionState(uint16_t* aScreen) {
}
NS_IMETHODIMP
nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx, Promise** aPromiseOut) {
nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx,
Promise** aPromiseOut) {
RefPtr<Promise> promiseHandle;
nsresult rv = GetPromise(aCx, promiseHandle);
if (NS_FAILED(rv)) {
@ -45,7 +46,8 @@ nsOSPermissionRequest::RequestVideoCapturePermission(JSContext* aCx, Promise** a
}
NS_IMETHODIMP
nsOSPermissionRequest::RequestAudioCapturePermission(JSContext* aCx, Promise** aPromiseOut) {
nsOSPermissionRequest::RequestAudioCapturePermission(JSContext* aCx,
Promise** aPromiseOut) {
RefPtr<Promise> promiseHandle;
nsresult rv = GetPromise(aCx, promiseHandle);
if (NS_FAILED(rv)) {

Просмотреть файл

@ -37,7 +37,8 @@ class CGLLibrary {
return true;
}
if (!mOGLLibrary) {
mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
mOGLLibrary =
PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
if (!mOGLLibrary) {
NS_WARNING("Couldn't load OpenGL Framework.");
return false;
@ -59,7 +60,8 @@ CGLLibrary sCGLLibrary;
GLContextCGL::GLContextCGL(const GLContextDesc& desc, NSOpenGLContext* context)
: GLContext(desc), mContext(context) {
CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallback, this);
CGDisplayRegisterReconfigurationCallback(DisplayReconfigurationCallback,
this);
}
GLContextCGL::~GLContextCGL() {
@ -89,33 +91,39 @@ bool GLContextCGL::MakeCurrentImpl() const {
// Use non-blocking swap in "ASAP mode".
// ASAP mode means that rendering is iterated as fast as possible.
// ASAP mode is entered when layout.frame_rate=0 (requires restart).
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank signal.
// When we're iterating as fast as possible, however, we want a non-blocking
// glSwapBuffers, which will happen when swapInt==0.
// If swapInt is 1, then glSwapBuffers will block and wait for a vblank
// signal. When we're iterating as fast as possible, however, we want a
// non-blocking glSwapBuffers, which will happen when swapInt==0.
GLint swapInt = StaticPrefs::layout_frame_rate() == 0 ? 0 : 1;
[mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
return true;
}
bool GLContextCGL::IsCurrentImpl() const { return [NSOpenGLContext currentContext] == mContext; }
bool GLContextCGL::IsCurrentImpl() const {
return [NSOpenGLContext currentContext] == mContext;
}
/* static */ void GLContextCGL::DisplayReconfigurationCallback(CGDirectDisplayID aDisplay,
CGDisplayChangeSummaryFlags aFlags,
void* aUserInfo) {
/* static */ void GLContextCGL::DisplayReconfigurationCallback(
CGDirectDisplayID aDisplay, CGDisplayChangeSummaryFlags aFlags,
void* aUserInfo) {
if (aFlags & kCGDisplaySetModeFlag) {
static_cast<GLContextCGL*>(aUserInfo)->mActiveGPUSwitchMayHaveOccurred = true;
static_cast<GLContextCGL*>(aUserInfo)->mActiveGPUSwitchMayHaveOccurred =
true;
}
}
static NSOpenGLContext* CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs) {
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
static NSOpenGLContext* CreateWithFormat(
const NSOpenGLPixelFormatAttribute* attribs) {
NSOpenGLPixelFormat* format =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (!format) {
NS_WARNING("Failed to create NSOpenGLPixelFormat.");
return nullptr;
}
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nullptr];
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format
shareContext:nullptr];
[format release];
@ -124,30 +132,40 @@ static NSOpenGLContext* CreateWithFormat(const NSOpenGLPixelFormatAttribute* att
// Get the "OpenGL display mask" for a fresh context. The return value of this
// function depends on the time at which this function is called.
// In practice, on a Macbook Pro with an integrated and a discrete GPU, this function returns the
// display mask for the GPU that currently drives the internal display.
// In practice, on a Macbook Pro with an integrated and a discrete GPU, this
// function returns the display mask for the GPU that currently drives the
// internal display.
//
// Quick reference of the concepts involved in the code below:
// GPU switch: On Mac devices with an integrated and a discrete GPU, a GPU switch changes which
// GPU drives the internal display. Both GPUs are still usable at all times. (When the
// integrated GPU is driving the internal display, using the discrete GPU can incur a longer
// warm-up cost.)
// Virtual screen: A CGL concept. A "virtual screen" corresponds to a GL renderer. There's one
// for the integrated GPU, one for each discrete GPU, and one for the Apple software renderer.
// The list of virtual screens is per-NSOpenGLPixelFormat; it is filtered down to only the
// renderers that support the requirements from the pixel format attributes. Indexes into this
// list (such as currentVirtualScreen) cannot be used interchangably across different
// NSOpenGLPixelFormat instances.
// Display mask: A bitset per GL renderer. Different renderers have disjoint display masks. The
// GPU switch: On Mac devices with an integrated and a discrete GPU, a GPU
// switch changes which
// GPU drives the internal display. Both GPUs are still usable at all times.
// (When the integrated GPU is driving the internal display, using the
// discrete GPU can incur a longer warm-up cost.)
// Virtual screen: A CGL concept. A "virtual screen" corresponds to a GL
// renderer. There's one
// for the integrated GPU, one for each discrete GPU, and one for the Apple
// software renderer. The list of virtual screens is
// per-NSOpenGLPixelFormat; it is filtered down to only the renderers that
// support the requirements from the pixel format attributes. Indexes into
// this list (such as currentVirtualScreen) cannot be used interchangably
// across different NSOpenGLPixelFormat instances.
// Display mask: A bitset per GL renderer. Different renderers have disjoint
// display masks. The
// Apple software renderer has all bits zeroed. For each CGDirectDisplayID,
// CGDisplayIDToOpenGLDisplayMask(displayID) returns a single bit in the display mask.
// CGDirectDisplayID: An ID for each (physical screen, GPU which can drive this screen) pair. The
// current CGDirectDisplayID for an NSScreen object can be obtained using [[[screen
// deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; it changes depending on
// which GPU is currently driving the screen.
// CGDisplayIDToOpenGLDisplayMask(displayID) returns a single bit in the
// display mask.
// CGDirectDisplayID: An ID for each (physical screen, GPU which can drive
// this screen) pair. The
// current CGDirectDisplayID for an NSScreen object can be obtained using
// [[[screen deviceDescription] objectForKey:@"NSScreenNumber"]
// unsignedIntValue]; it changes depending on which GPU is currently driving
// the screen.
static CGOpenGLDisplayMask GetFreshContextDisplayMask() {
NSOpenGLPixelFormatAttribute attribs[] = {NSOpenGLPFAAllowOfflineRenderers, 0};
NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
NSOpenGLPixelFormatAttribute attribs[] = {NSOpenGLPFAAllowOfflineRenderers,
0};
NSOpenGLPixelFormat* pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
MOZ_RELEASE_ASSERT(pixelFormat);
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
shareContext:nullptr];
@ -185,13 +203,15 @@ void GLContextCGL::MigrateToActiveGPU() {
return;
}
// Find the "virtual screen" with a display mask that matches newPreferredDisplayMask, if
// available, and switch the context over to it.
// This code was inspired by equivalent functionality in -[NSOpenGLContext update] which only
// kicks in for contexts that present via a CAOpenGLLayer.
// Find the "virtual screen" with a display mask that matches
// newPreferredDisplayMask, if available, and switch the context over to it.
// This code was inspired by equivalent functionality in -[NSOpenGLContext
// update] which only kicks in for contexts that present via a CAOpenGLLayer.
for (const auto i : IntegerRange([pixelFormat numberOfVirtualScreens])) {
GLint displayMask = 0;
[pixelFormat getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:i];
[pixelFormat getValues:&displayMask
forAttribute:NSOpenGLPFAScreenMask
forVirtualScreen:i];
if (IsSameGPU(displayMask, newPreferredDisplayMask)) {
CGLSetVirtualScreen([mContext CGLContextObj], i);
return;
@ -212,7 +232,9 @@ bool GLContextCGL::SwapBuffers() {
return true;
}
void GLContextCGL::GetWSIInfo(nsCString* const out) const { out->AppendLiteral("CGL"); }
void GLContextCGL::GetWSIInfo(nsCString* const out) const {
out->AppendLiteral("CGL");
}
Maybe<SymbolLoader> GLContextCGL::GetSymbolLoader() const {
const auto& lib = sCGLLibrary.Library();
@ -220,7 +242,8 @@ Maybe<SymbolLoader> GLContextCGL::GetSymbolLoader() const {
}
already_AddRefed<GLContext> GLContextProviderCGL::CreateForCompositorWidget(
CompositorWidget* aCompositorWidget, bool aHardwareWebRender, bool aForceAccelerated) {
CompositorWidget* aCompositorWidget, bool aHardwareWebRender,
bool aForceAccelerated) {
CreateContextFlags flags = CreateContextFlags::ALLOW_OFFLINE_RENDERER;
if (aForceAccelerated) {
flags |= CreateContextFlags::FORBID_SOFTWARE;
@ -232,7 +255,8 @@ already_AddRefed<GLContext> GLContextProviderCGL::CreateForCompositorWidget(
return CreateHeadless({flags}, &failureUnused);
}
static RefPtr<GLContextCGL> CreateOffscreenFBOContext(GLContextCreateDesc desc) {
static RefPtr<GLContextCGL> CreateOffscreenFBOContext(
GLContextCreateDesc desc) {
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
@ -247,8 +271,9 @@ static RefPtr<GLContextCGL> CreateOffscreenFBOContext(GLContextCreateDesc desc)
}
if (flags & CreateContextFlags::ALLOW_OFFLINE_RENDERER ||
!(flags & CreateContextFlags::HIGH_POWER)) {
// This is really poorly named on Apple's part, but "AllowOfflineRenderers" means
// that we want to allow running on the iGPU instead of requiring the dGPU.
// This is really poorly named on Apple's part, but "AllowOfflineRenderers"
// means that we want to allow running on the iGPU instead of requiring the
// dGPU.
attribs.push_back(NSOpenGLPFAAllowOfflineRenderers);
}
@ -298,8 +323,8 @@ static RefPtr<GLContextCGL> CreateOffscreenFBOContext(GLContextCreateDesc desc)
return glContext;
}
already_AddRefed<GLContext> GLContextProviderCGL::CreateHeadless(const GLContextCreateDesc& desc,
nsACString* const out_failureId) {
already_AddRefed<GLContext> GLContextProviderCGL::CreateHeadless(
const GLContextCreateDesc& desc, nsACString* const out_failureId) {
auto gl = CreateOffscreenFBOContext(desc);
if (!gl) {
*out_failureId = "FEATURE_FAILURE_CGL_FBO"_ns;

Просмотреть файл

@ -52,7 +52,8 @@ bool GLContextEAGL::AttachToWindow(nsIWidget* aWidget) {
// This should only be called once
MOZ_ASSERT(!mBackbufferFB && !mBackbufferRB);
UIView* view = reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
UIView* view =
reinterpret_cast<UIView*>(aWidget->GetNativeData(NS_NATIVE_WIDGET));
if (!view) {
MOZ_CRASH("no view!");
@ -82,10 +83,11 @@ bool GLContextEAGL::RecreateRB() {
[mContext renderbufferStorage:LOCAL_GL_RENDERBUFFER fromDrawable:layer];
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mBackbufferFB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_RENDERBUFFER,
mBackbufferRB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER, mBackbufferRB);
return LOCAL_GL_FRAMEBUFFER_COMPLETE == fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
return LOCAL_GL_FRAMEBUFFER_COMPLETE ==
fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
}
bool GLContextEAGL::MakeCurrentImpl() const {
@ -97,7 +99,9 @@ bool GLContextEAGL::MakeCurrentImpl() const {
return true;
}
bool GLContextEAGL::IsCurrentImpl() const { return [EAGLContext currentContext] == mContext; }
bool GLContextEAGL::IsCurrentImpl() const {
return [EAGLContext currentContext] == mContext;
}
static PRFuncPtr GLAPIENTRY GetLoadedProcAddress(const char* const name) {
PRLibrary* lib = nullptr;
@ -121,7 +125,9 @@ bool GLContextEAGL::SwapBuffers() {
return true;
}
void GLContextEAGL::GetWSIInfo(nsCString* const out) const { out->AppendLiteral("EAGL"); }
void GLContextEAGL::GetWSIInfo(nsCString* const out) const {
out->AppendLiteral("EAGL");
}
static GLContextEAGL* GetGlobalContextEAGL() {
return static_cast<GLContextEAGL*>(GLContextProviderEAGL::GetGlobalContext());
@ -129,14 +135,16 @@ static GLContextEAGL* GetGlobalContextEAGL() {
static RefPtr<GLContext> CreateEAGLContext(const GLContextDesc& desc,
GLContextEAGL* sharedContext) {
EAGLRenderingAPI apis[] = {kEAGLRenderingAPIOpenGLES3, kEAGLRenderingAPIOpenGLES2};
EAGLRenderingAPI apis[] = {kEAGLRenderingAPIOpenGLES3,
kEAGLRenderingAPIOpenGLES2};
// Try to create a GLES3 context if we can, otherwise fall back to GLES2
EAGLContext* context = nullptr;
for (EAGLRenderingAPI api : apis) {
if (sharedContext) {
context = [[EAGLContext alloc] initWithAPI:api
sharegroup:sharedContext->GetEAGLContext().sharegroup];
context = [[EAGLContext alloc]
initWithAPI:api
sharegroup:sharedContext->GetEAGLContext().sharegroup];
} else {
context = [[EAGLContext alloc] initWithAPI:api];
}
@ -150,7 +158,8 @@ static RefPtr<GLContext> CreateEAGLContext(const GLContextDesc& desc,
return nullptr;
}
RefPtr<GLContextEAGL> glContext = new GLContextEAGL(desc, context, sharedContext);
RefPtr<GLContextEAGL> glContext =
new GLContextEAGL(desc, context, sharedContext);
if (!glContext->Init()) {
glContext = nullptr;
return nullptr;
@ -160,7 +169,8 @@ static RefPtr<GLContext> CreateEAGLContext(const GLContextDesc& desc,
}
already_AddRefed<GLContext> GLContextProviderEAGL::CreateForCompositorWidget(
CompositorWidget* aCompositorWidget, bool aHardwareWebRender, bool aForceAccelerated) {
CompositorWidget* aCompositorWidget, bool aHardwareWebRender,
bool aForceAccelerated) {
if (!aCompositorWidget) {
MOZ_ASSERT(false);
return nullptr;
@ -172,7 +182,8 @@ already_AddRefed<GLContext> GLContextProviderEAGL::CreateForCompositorWidget(
return nullptr;
}
if (!GLContextEAGL::Cast(glContext)->AttachToWindow(aCompositorWidget->RealWidget())) {
if (!GLContextEAGL::Cast(glContext)->AttachToWindow(
aCompositorWidget->RealWidget())) {
return nullptr;
}
@ -193,7 +204,8 @@ GLContext* GLContextProviderEAGL::GetGlobalContext() {
if (!triedToCreateContext) {
triedToCreateContext = true;
MOZ_RELEASE_ASSERT(!gGlobalContext, "GFX: Global GL context already initialized.");
MOZ_RELEASE_ASSERT(!gGlobalContext,
"GFX: Global GL context already initialized.");
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
gGlobalContext = temp;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nullptr; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -36,11 +36,13 @@ using gl::GLContextCGL;
// SurfacePoolCA::LockedPool
SurfacePoolCA::LockedPool::LockedPool(size_t aPoolSizeLimit) : mPoolSizeLimit(aPoolSizeLimit) {}
SurfacePoolCA::LockedPool::LockedPool(size_t aPoolSizeLimit)
: mPoolSizeLimit(aPoolSizeLimit) {}
SurfacePoolCA::LockedPool::~LockedPool() {
MOZ_RELEASE_ASSERT(mWrappers.empty(),
"Any outstanding wrappers should have kept the surface pool alive");
MOZ_RELEASE_ASSERT(
mWrappers.empty(),
"Any outstanding wrappers should have kept the surface pool alive");
MOZ_RELEASE_ASSERT(mInUseEntries.empty(),
"Leak! No more surfaces should be in use at this point.");
// Remove all entries in mPendingEntries and mAvailableEntries.
@ -50,8 +52,8 @@ SurfacePoolCA::LockedPool::~LockedPool() {
});
}
RefPtr<SurfacePoolCAWrapperForGL> SurfacePoolCA::LockedPool::GetWrapperForGL(SurfacePoolCA* aPool,
GLContext* aGL) {
RefPtr<SurfacePoolCAWrapperForGL> SurfacePoolCA::LockedPool::GetWrapperForGL(
SurfacePoolCA* aPool, GLContext* aGL) {
auto& wrapper = mWrappers[aGL];
if (!wrapper) {
wrapper = new SurfacePoolCAWrapperForGL(aPool, aGL);
@ -71,7 +73,8 @@ void SurfacePoolCA::LockedPool::DestroyGLResourcesForContext(GLContext* aGL) {
template <typename F>
void SurfacePoolCA::LockedPool::MutateEntryStorage(const char* aMutationType,
const gfx::IntSize& aSize, F aFn) {
const gfx::IntSize& aSize,
F aFn) {
[[maybe_unused]] size_t inUseCountBefore = mInUseEntries.size();
[[maybe_unused]] size_t pendingCountBefore = mPendingEntries.Length();
[[maybe_unused]] size_t availableCountBefore = mAvailableEntries.Length();
@ -84,9 +87,11 @@ void SurfacePoolCA::LockedPool::MutateEntryStorage(const char* aMutationType,
"SurfacePool", GRAPHICS, MarkerTiming::IntervalUntilNowFrom(before),
nsPrintfCString("%d -> %d in use | %d -> %d waiting for | %d -> %d "
"available | %s %dx%d | %dMB total memory",
int(inUseCountBefore), int(mInUseEntries.size()), int(pendingCountBefore),
int(mPendingEntries.Length()), int(availableCountBefore),
int(mAvailableEntries.Length()), aMutationType, aSize.width, aSize.height,
int(inUseCountBefore), int(mInUseEntries.size()),
int(pendingCountBefore), int(mPendingEntries.Length()),
int(availableCountBefore),
int(mAvailableEntries.Length()), aMutationType,
aSize.width, aSize.height,
int(EstimateTotalMemory() / 1000 / 1000)));
}
}
@ -126,8 +131,8 @@ uint64_t SurfacePoolCA::LockedPool::EstimateTotalMemory() {
return memBytes;
}
bool SurfacePoolCA::LockedPool::CanRecycleSurfaceForRequest(const SurfacePoolEntry& aEntry,
const IntSize& aSize, GLContext* aGL) {
bool SurfacePoolCA::LockedPool::CanRecycleSurfaceForRequest(
const SurfacePoolEntry& aEntry, const IntSize& aSize, GLContext* aGL) {
if (aEntry.mSize != aSize) {
return false;
}
@ -137,14 +142,16 @@ bool SurfacePoolCA::LockedPool::CanRecycleSurfaceForRequest(const SurfacePoolEnt
return true;
}
CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::LockedPool::ObtainSurfaceFromPool(const IntSize& aSize,
GLContext* aGL) {
// Do a linear scan through mAvailableEntries to find an eligible surface, going from oldest to
// newest. The size of this array is limited, so the linear scan is fast.
auto iterToRecycle = std::find_if(mAvailableEntries.begin(), mAvailableEntries.end(),
[&](const SurfacePoolEntry& aEntry) {
return CanRecycleSurfaceForRequest(aEntry, aSize, aGL);
});
CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::LockedPool::ObtainSurfaceFromPool(
const IntSize& aSize, GLContext* aGL) {
// Do a linear scan through mAvailableEntries to find an eligible surface,
// going from oldest to newest. The size of this array is limited, so the
// linear scan is fast.
auto iterToRecycle =
std::find_if(mAvailableEntries.begin(), mAvailableEntries.end(),
[&](const SurfacePoolEntry& aEntry) {
return CanRecycleSurfaceForRequest(aEntry, aSize, aGL);
});
if (iterToRecycle != mAvailableEntries.end()) {
CFTypeRefPtr<IOSurfaceRef> surface = iterToRecycle->mIOSurface;
MOZ_RELEASE_ASSERT(surface.get(), "Available surfaces should be non-null.");
@ -156,18 +163,22 @@ CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::LockedPool::ObtainSurfaceFromPool(cons
return surface;
}
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("IOSurface creation", GRAPHICS_TileAllocation,
nsPrintfCString("%dx%d", aSize.width, aSize.height));
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
"IOSurface creation", GRAPHICS_TileAllocation,
nsPrintfCString("%dx%d", aSize.width, aSize.height));
CFTypeRefPtr<IOSurfaceRef> surface =
CFTypeRefPtr<IOSurfaceRef>::WrapUnderCreateRule(IOSurfaceCreate((__bridge CFDictionaryRef) @{
(__bridge NSString*)kIOSurfaceWidth : @(aSize.width),
(__bridge NSString*)kIOSurfaceHeight : @(aSize.height),
(__bridge NSString*)kIOSurfacePixelFormat : @(kCVPixelFormatType_32BGRA),
(__bridge NSString*)kIOSurfaceBytesPerElement : @(4),
}));
CFTypeRefPtr<IOSurfaceRef>::WrapUnderCreateRule(
IOSurfaceCreate((__bridge CFDictionaryRef) @{
(__bridge NSString*)kIOSurfaceWidth : @(aSize.width),
(__bridge NSString*)kIOSurfaceHeight : @(aSize.height),
(__bridge NSString*)
kIOSurfacePixelFormat : @(kCVPixelFormatType_32BGRA),
(__bridge NSString*)kIOSurfaceBytesPerElement : @(4),
}));
if (surface) {
if (StaticPrefs::gfx_color_management_native_srgb()) {
IOSurfaceSetValue(surface.get(), CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
IOSurfaceSetValue(surface.get(), CFSTR("IOSurfaceColorSpace"),
kCGColorSpaceSRGB);
}
// Create a new entry in mInUseEntries.
MutateEntryStorage("Create", aSize, [&]() {
@ -177,16 +188,18 @@ CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::LockedPool::ObtainSurfaceFromPool(cons
return surface;
}
void SurfacePoolCA::LockedPool::ReturnSurfaceToPool(CFTypeRefPtr<IOSurfaceRef> aSurface) {
void SurfacePoolCA::LockedPool::ReturnSurfaceToPool(
CFTypeRefPtr<IOSurfaceRef> aSurface) {
auto inUseEntryIter = mInUseEntries.find(aSurface);
MOZ_RELEASE_ASSERT(inUseEntryIter != mInUseEntries.end());
if (IOSurfaceIsInUse(aSurface.get())) {
// Move the entry from mInUseEntries to mPendingEntries.
MutateEntryStorage("Start waiting for", IntSize(inUseEntryIter->second.mSize), [&]() {
mPendingEntries.AppendElement(
PendingSurfaceEntry{std::move(inUseEntryIter->second), mCollectionGeneration, 0});
mInUseEntries.erase(inUseEntryIter);
});
MutateEntryStorage(
"Start waiting for", IntSize(inUseEntryIter->second.mSize), [&]() {
mPendingEntries.AppendElement(PendingSurfaceEntry{
std::move(inUseEntryIter->second), mCollectionGeneration, 0});
mInUseEntries.erase(inUseEntryIter);
});
} else {
// Move the entry from mInUseEntries to mAvailableEntries.
MOZ_RELEASE_ASSERT(inUseEntryIter->second.mIOSurface.get(),
@ -199,14 +212,16 @@ void SurfacePoolCA::LockedPool::ReturnSurfaceToPool(CFTypeRefPtr<IOSurfaceRef> a
}
void SurfacePoolCA::LockedPool::EnforcePoolSizeLimit() {
// Enforce the pool size limit, removing least-recently-used entries as necessary.
// Enforce the pool size limit, removing least-recently-used entries as
// necessary.
while (mAvailableEntries.Length() > mPoolSizeLimit) {
MutateEntryStorage("Evict", IntSize(mAvailableEntries[0].mSize),
[&]() { mAvailableEntries.RemoveElementAt(0); });
}
}
uint64_t SurfacePoolCA::LockedPool::CollectPendingSurfaces(uint64_t aCheckGenerationsUpTo) {
uint64_t SurfacePoolCA::LockedPool::CollectPendingSurfaces(
uint64_t aCheckGenerationsUpTo) {
mCollectionGeneration++;
// Loop from back to front, potentially deleting items as we iterate.
@ -218,18 +233,21 @@ uint64_t SurfacePoolCA::LockedPool::CollectPendingSurfaces(uint64_t aCheckGenera
if (pendingSurf.mPreviousCheckGeneration > aCheckGenerationsUpTo) {
continue;
}
// Check if the window server is still using the surface. As long as it is doing that, we cannot
// move the surface to mAvailableSurfaces because anything we draw to it could reach the screen
// in a place where we don't expect it.
// Check if the window server is still using the surface. As long as it is
// doing that, we cannot move the surface to mAvailableSurfaces because
// anything we draw to it could reach the screen in a place where we don't
// expect it.
if (IOSurfaceIsInUse(pendingSurf.mEntry.mIOSurface.get())) {
// The surface is still in use. Update mPreviousCheckGeneration and mCheckCount.
// The surface is still in use. Update mPreviousCheckGeneration and
// mCheckCount.
pendingSurf.mPreviousCheckGeneration = mCollectionGeneration;
pendingSurf.mCheckCount++;
if (pendingSurf.mCheckCount >= 30) {
// The window server has been holding on to this surface for an unreasonably long time. This
// is known to happen sometimes, for example in occluded windows or after a GPU switch. In
// that case, release our references to the surface so that it's Not Our Problem anymore.
// Remove the entry from mPendingEntries.
// The window server has been holding on to this surface for an
// unreasonably long time. This is known to happen sometimes, for
// example in occluded windows or after a GPU switch. In that case,
// release our references to the surface so that it's Not Our Problem
// anymore. Remove the entry from mPendingEntries.
MutateEntryStorage("Eject", IntSize(pendingSurf.mEntry.mSize),
[&]() { mPendingEntries.RemoveElementAt(i); });
}
@ -238,30 +256,33 @@ uint64_t SurfacePoolCA::LockedPool::CollectPendingSurfaces(uint64_t aCheckGenera
// Move the entry from mPendingEntries to mAvailableEntries.
MOZ_RELEASE_ASSERT(pendingSurf.mEntry.mIOSurface.get(),
"Pending surfaces should be non-null.");
MutateEntryStorage("Stop waiting for", IntSize(pendingSurf.mEntry.mSize), [&]() {
mAvailableEntries.AppendElement(std::move(pendingSurf.mEntry));
mPendingEntries.RemoveElementAt(i);
});
MutateEntryStorage(
"Stop waiting for", IntSize(pendingSurf.mEntry.mSize), [&]() {
mAvailableEntries.AppendElement(std::move(pendingSurf.mEntry));
mPendingEntries.RemoveElementAt(i);
});
}
}
return mCollectionGeneration;
}
void SurfacePoolCA::LockedPool::OnWrapperDestroyed(gl::GLContext* aGL,
SurfacePoolCAWrapperForGL* aWrapper) {
void SurfacePoolCA::LockedPool::OnWrapperDestroyed(
gl::GLContext* aGL, SurfacePoolCAWrapperForGL* aWrapper) {
if (aGL) {
DestroyGLResourcesForContext(aGL);
}
auto iter = mWrappers.find(aGL);
MOZ_RELEASE_ASSERT(iter != mWrappers.end());
MOZ_RELEASE_ASSERT(iter->second == aWrapper, "Only one SurfacePoolCAWrapperForGL object should "
"exist for each GLContext* at any time");
MOZ_RELEASE_ASSERT(iter->second == aWrapper,
"Only one SurfacePoolCAWrapperForGL object should "
"exist for each GLContext* at any time");
mWrappers.erase(iter);
}
Maybe<GLuint> SurfacePoolCA::LockedPool::GetFramebufferForSurface(
CFTypeRefPtr<IOSurfaceRef> aSurface, GLContext* aGL, bool aNeedsDepthBuffer) {
CFTypeRefPtr<IOSurfaceRef> aSurface, GLContext* aGL,
bool aNeedsDepthBuffer) {
MOZ_RELEASE_ASSERT(aGL);
auto inUseEntryIter = mInUseEntries.find(aSurface);
@ -271,7 +292,8 @@ Maybe<GLuint> SurfacePoolCA::LockedPool::GetFramebufferForSurface(
if (entry.mGLResources) {
// We have an existing framebuffer.
MOZ_RELEASE_ASSERT(entry.mGLResources->mGLContext == aGL,
"Recycled surface that still had GL resources from a different GL context. "
"Recycled surface that still had GL resources from a "
"different GL context. "
"This shouldn't happen.");
if (!aNeedsDepthBuffer || entry.mGLResources->mFramebuffer->HasDepth()) {
return Some(entry.mGLResources->mFramebuffer->mFB);
@ -294,13 +316,16 @@ Maybe<GLuint> SurfacePoolCA::LockedPool::GetFramebufferForSurface(
GLuint tex = aGL->CreateTexture();
{
const gl::ScopedBindTexture bindTex(aGL, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
CGLTexImageIOSurface2D(cgl->GetCGLContext(), LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_RGBA,
entry.mSize.width, entry.mSize.height, LOCAL_GL_BGRA,
LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV, entry.mIOSurface.get(), 0);
const gl::ScopedBindTexture bindTex(aGL, tex,
LOCAL_GL_TEXTURE_RECTANGLE_ARB);
CGLTexImageIOSurface2D(cgl->GetCGLContext(), LOCAL_GL_TEXTURE_RECTANGLE_ARB,
LOCAL_GL_RGBA, entry.mSize.width, entry.mSize.height,
LOCAL_GL_BGRA, LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV,
entry.mIOSurface.get(), 0);
}
auto fb = CreateFramebufferForTexture(aGL, entry.mSize, tex, aNeedsDepthBuffer);
auto fb =
CreateFramebufferForTexture(aGL, entry.mSize, tex, aNeedsDepthBuffer);
if (!fb) {
// Framebuffer completeness check may have failed.
return {};
@ -311,10 +336,12 @@ Maybe<GLuint> SurfacePoolCA::LockedPool::GetFramebufferForSurface(
return Some(fbo);
}
RefPtr<gl::DepthAndStencilBuffer> SurfacePoolCA::LockedPool::GetDepthBufferForSharing(
GLContext* aGL, const IntSize& aSize) {
RefPtr<gl::DepthAndStencilBuffer>
SurfacePoolCA::LockedPool::GetDepthBufferForSharing(GLContext* aGL,
const IntSize& aSize) {
// Clean out entries for which the weak pointer has become null.
mDepthBuffers.RemoveElementsBy([&](const DepthBufferEntry& entry) { return !entry.mBuffer; });
mDepthBuffers.RemoveElementsBy(
[&](const DepthBufferEntry& entry) { return !entry.mBuffer; });
for (const auto& entry : mDepthBuffers) {
if (entry.mGLContext == aGL && entry.mSize == aSize) {
@ -324,22 +351,29 @@ RefPtr<gl::DepthAndStencilBuffer> SurfacePoolCA::LockedPool::GetDepthBufferForSh
return nullptr;
}
UniquePtr<gl::MozFramebuffer> SurfacePoolCA::LockedPool::CreateFramebufferForTexture(
GLContext* aGL, const IntSize& aSize, GLuint aTexture, bool aNeedsDepthBuffer) {
UniquePtr<gl::MozFramebuffer>
SurfacePoolCA::LockedPool::CreateFramebufferForTexture(GLContext* aGL,
const IntSize& aSize,
GLuint aTexture,
bool aNeedsDepthBuffer) {
if (aNeedsDepthBuffer) {
// Try to find an existing depth buffer of aSize in aGL and create a framebuffer that shares it.
// Try to find an existing depth buffer of aSize in aGL and create a
// framebuffer that shares it.
if (auto buffer = GetDepthBufferForSharing(aGL, aSize)) {
return gl::MozFramebuffer::CreateForBackingWithSharedDepthAndStencil(
aSize, 0, LOCAL_GL_TEXTURE_RECTANGLE_ARB, aTexture, buffer);
}
}
// No depth buffer needed or we didn't find one. Create a framebuffer with a new depth buffer and
// store a weak pointer to the new depth buffer in mDepthBuffers.
// No depth buffer needed or we didn't find one. Create a framebuffer with a
// new depth buffer and store a weak pointer to the new depth buffer in
// mDepthBuffers.
UniquePtr<gl::MozFramebuffer> fb = gl::MozFramebuffer::CreateForBacking(
aGL, aSize, 0, aNeedsDepthBuffer, LOCAL_GL_TEXTURE_RECTANGLE_ARB, aTexture);
aGL, aSize, 0, aNeedsDepthBuffer, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
aTexture);
if (fb && fb->GetDepthAndStencilBuffer()) {
mDepthBuffers.AppendElement(DepthBufferEntry{aGL, aSize, fb->GetDepthAndStencilBuffer().get()});
mDepthBuffers.AppendElement(
DepthBufferEntry{aGL, aSize, fb->GetDepthAndStencilBuffer().get()});
}
return fb;
@ -347,8 +381,9 @@ UniquePtr<gl::MozFramebuffer> SurfacePoolCA::LockedPool::CreateFramebufferForTex
// SurfacePoolHandleCA
SurfacePoolHandleCA::SurfacePoolHandleCA(RefPtr<SurfacePoolCAWrapperForGL>&& aPoolWrapper,
uint64_t aCurrentCollectionGeneration)
SurfacePoolHandleCA::SurfacePoolHandleCA(
RefPtr<SurfacePoolCAWrapperForGL>&& aPoolWrapper,
uint64_t aCurrentCollectionGeneration)
: mPoolWrapper(aPoolWrapper),
mPreviousFrameCollectionGeneration(
"SurfacePoolHandleCA::mPreviousFrameCollectionGeneration") {
@ -363,20 +398,24 @@ void SurfacePoolHandleCA::OnBeginFrame() {
*generation = mPoolWrapper->mPool->CollectPendingSurfaces(*generation);
}
void SurfacePoolHandleCA::OnEndFrame() { mPoolWrapper->mPool->EnforcePoolSizeLimit(); }
void SurfacePoolHandleCA::OnEndFrame() {
mPoolWrapper->mPool->EnforcePoolSizeLimit();
}
CFTypeRefPtr<IOSurfaceRef> SurfacePoolHandleCA::ObtainSurfaceFromPool(const IntSize& aSize) {
CFTypeRefPtr<IOSurfaceRef> SurfacePoolHandleCA::ObtainSurfaceFromPool(
const IntSize& aSize) {
return mPoolWrapper->mPool->ObtainSurfaceFromPool(aSize, mPoolWrapper->mGL);
}
void SurfacePoolHandleCA::ReturnSurfaceToPool(CFTypeRefPtr<IOSurfaceRef> aSurface) {
void SurfacePoolHandleCA::ReturnSurfaceToPool(
CFTypeRefPtr<IOSurfaceRef> aSurface) {
mPoolWrapper->mPool->ReturnSurfaceToPool(aSurface);
}
Maybe<GLuint> SurfacePoolHandleCA::GetFramebufferForSurface(CFTypeRefPtr<IOSurfaceRef> aSurface,
bool aNeedsDepthBuffer) {
return mPoolWrapper->mPool->GetFramebufferForSurface(aSurface, mPoolWrapper->mGL,
aNeedsDepthBuffer);
Maybe<GLuint> SurfacePoolHandleCA::GetFramebufferForSurface(
CFTypeRefPtr<IOSurfaceRef> aSurface, bool aNeedsDepthBuffer) {
return mPoolWrapper->mPool->GetFramebufferForSurface(
aSurface, mPoolWrapper->mGL, aNeedsDepthBuffer);
}
// SurfacePoolCA
@ -405,8 +444,8 @@ void SurfacePoolCA::DestroyGLResourcesForContext(GLContext* aGL) {
pool->DestroyGLResourcesForContext(aGL);
}
CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::ObtainSurfaceFromPool(const IntSize& aSize,
GLContext* aGL) {
CFTypeRefPtr<IOSurfaceRef> SurfacePoolCA::ObtainSurfaceFromPool(
const IntSize& aSize, GLContext* aGL) {
auto pool = mPool.Lock();
return pool->ObtainSurfaceFromPool(aSize, aGL);
}
@ -425,13 +464,15 @@ void SurfacePoolCA::EnforcePoolSizeLimit() {
pool->EnforcePoolSizeLimit();
}
Maybe<GLuint> SurfacePoolCA::GetFramebufferForSurface(CFTypeRefPtr<IOSurfaceRef> aSurface,
GLContext* aGL, bool aNeedsDepthBuffer) {
Maybe<GLuint> SurfacePoolCA::GetFramebufferForSurface(
CFTypeRefPtr<IOSurfaceRef> aSurface, GLContext* aGL,
bool aNeedsDepthBuffer) {
auto pool = mPool.Lock();
return pool->GetFramebufferForSurface(aSurface, aGL, aNeedsDepthBuffer);
}
void SurfacePoolCA::OnWrapperDestroyed(gl::GLContext* aGL, SurfacePoolCAWrapperForGL* aWrapper) {
void SurfacePoolCA::OnWrapperDestroyed(gl::GLContext* aGL,
SurfacePoolCAWrapperForGL* aWrapper) {
auto pool = mPool.Lock();
return pool->OnWrapperDestroyed(aGL, aWrapper);
}

Просмотреть файл

@ -15,10 +15,14 @@
namespace mozilla::gfx {
static size_t PutBytesNull(void* info, const void* buffer, size_t count) { return count; }
static size_t PutBytesNull(void* info, const void* buffer, size_t count) {
return count;
}
PrintTargetCG::PrintTargetCG(CGContextRef aPrintToStreamContext, PMPrintSession aPrintSession,
PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
PrintTargetCG::PrintTargetCG(CGContextRef aPrintToStreamContext,
PMPrintSession aPrintSession,
PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings,
const IntSize& aSize)
: PrintTarget(/* aCairoSurface */ nullptr, aSize),
mPrintToStreamContext(aPrintToStreamContext),
@ -53,14 +57,16 @@ PrintTargetCG::~PrintTargetCG() {
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
static size_t WriteStreamBytes(void* aInfo, const void* aBuffer, size_t aCount) {
static size_t WriteStreamBytes(void* aInfo, const void* aBuffer,
size_t aCount) {
auto* stream = static_cast<nsIOutputStream*>(aInfo);
auto* data = static_cast<const char*>(aBuffer);
size_t remaining = aCount;
do {
uint32_t wrote = 0;
// Handle potential narrowing from size_t to uint32_t.
uint32_t toWrite = uint32_t(std::min(remaining, size_t(std::numeric_limits<uint32_t>::max())));
uint32_t toWrite = uint32_t(
std::min(remaining, size_t(std::numeric_limits<uint32_t>::max())));
if (NS_WARN_IF(NS_FAILED(stream->Write(data, toWrite, &wrote)))) {
break;
}
@ -87,21 +93,25 @@ static CGContextRef CreatePrintToStreamContext(nsIOutputStream* aOutputStream,
CGDataConsumerRef consumer = CGDataConsumerCreate(aOutputStream, &callbacks);
// This metadata is added by the CorePrinting APIs in the non-stream case.
NSString* bundleName =
[NSBundle.mainBundle.localizedInfoDictionary objectForKey:(NSString*)kCFBundleNameKey];
NSString* bundleName = [NSBundle.mainBundle.localizedInfoDictionary
objectForKey:(NSString*)kCFBundleNameKey];
CFMutableDictionaryRef auxiliaryInfo = CFDictionaryCreateMutable(
kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(auxiliaryInfo, kCGPDFContextCreator, (__bridge CFStringRef)bundleName);
kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(auxiliaryInfo, kCGPDFContextCreator,
(__bridge CFStringRef)bundleName);
CGContextRef pdfContext = CGPDFContextCreate(consumer, &pageBox, auxiliaryInfo);
CGContextRef pdfContext =
CGPDFContextCreate(consumer, &pageBox, auxiliaryInfo);
CGDataConsumerRelease(consumer);
CFRelease(auxiliaryInfo);
return pdfContext;
}
/* static */ already_AddRefed<PrintTargetCG> PrintTargetCG::CreateOrNull(
nsIOutputStream* aOutputStream, PMPrintSession aPrintSession, PMPageFormat aPageFormat,
PMPrintSettings aPrintSettings, const IntSize& aSize) {
nsIOutputStream* aOutputStream, PMPrintSession aPrintSession,
PMPageFormat aPageFormat, PMPrintSettings aPrintSettings,
const IntSize& aSize) {
if (!Factory::CheckSurfaceSize(aSize)) {
return nullptr;
}
@ -114,8 +124,8 @@ static CGContextRef CreatePrintToStreamContext(nsIOutputStream* aOutputStream,
}
}
RefPtr<PrintTargetCG> target =
new PrintTargetCG(printToStreamContext, aPrintSession, aPageFormat, aPrintSettings, aSize);
RefPtr<PrintTargetCG> target = new PrintTargetCG(
printToStreamContext, aPrintSession, aPageFormat, aPrintSettings, aSize);
return target.forget();
}
@ -129,8 +139,8 @@ already_AddRefed<DrawTarget> PrintTargetCG::GetReferenceDrawTarget() {
CGContextRef pdfContext = CGPDFContextCreate(consumer, nullptr, nullptr);
CGDataConsumerRelease(consumer);
cairo_surface_t* similar =
cairo_quartz_surface_create_for_cg_context(pdfContext, size.width, size.height);
cairo_surface_t* similar = cairo_quartz_surface_create_for_cg_context(
pdfContext, size.width, size.height);
CGContextRelease(pdfContext);
@ -138,7 +148,8 @@ already_AddRefed<DrawTarget> PrintTargetCG::GetReferenceDrawTarget() {
return nullptr;
}
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForCairoSurface(similar, size);
RefPtr<DrawTarget> dt =
Factory::CreateDrawTargetForCairoSurface(similar, size);
// The DT addrefs the surface, so we need drop our own reference to it:
cairo_surface_destroy(similar);
@ -152,7 +163,8 @@ already_AddRefed<DrawTarget> PrintTargetCG::GetReferenceDrawTarget() {
return do_AddRef(mRefDT);
}
nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName,
nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@ -182,7 +194,8 @@ nsresult PrintTargetCG::BeginPrinting(const nsAString& aTitle, const nsAString&
status = ::PMSetLastPage(mPrintSettings, aEndPage, false);
NS_ASSERTION(status == noErr, "PMSetLastPage failed");
status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings, mPageFormat);
status = ::PMSessionBeginCGDocumentNoDialog(mPrintSession, mPrintSettings,
mPageFormat);
return status == noErr ? NS_OK : NS_ERROR_ABORT;
@ -224,11 +237,13 @@ nsresult PrintTargetCG::BeginPage(const IntSize& aSizeInPoints) {
if (StaticPrefs::layout_css_page_orientation_enabled()) {
::PMOrientation pageOrientation =
aSizeInPoints.width < aSizeInPoints.height ? kPMPortrait : kPMLandscape;
aSizeInPoints.width < aSizeInPoints.height ? kPMPortrait
: kPMLandscape;
::PMSetOrientation(mPageFormat, pageOrientation, kPMUnlocked);
// We don't need to reset the orientation, since we set it for every page.
}
OSStatus status = ::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, nullptr);
OSStatus status =
::PMSessionBeginPageNoDialog(mPrintSession, mPageFormat, nullptr);
if (status != noErr) {
return NS_ERROR_ABORT;
}
@ -257,7 +272,8 @@ nsresult PrintTargetCG::BeginPage(const IntSize& aSizeInPoints) {
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
cairo_surface_t* surface = cairo_quartz_surface_create_for_cg_context(context, width, height);
cairo_surface_t* surface =
cairo_quartz_surface_create_for_cg_context(context, width, height);
if (cairo_surface_status(surface)) {
return NS_ERROR_FAILURE;

Просмотреть файл

@ -63,8 +63,9 @@ static void GetStringForNSString(const NSString* aSrc, nsAString& aDest) {
}
static NSString* GetNSStringForString(const nsAString& aSrc) {
return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(aSrc.BeginReading())
length:aSrc.Length()];
return [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(aSrc.BeginReading())
length:aSrc.Length()];
}
#define LOG_FONTLIST(args) \
@ -77,7 +78,8 @@ static NSString* GetNSStringForString(const nsAString& aSrc) {
class gfxMacFontFamily final : public CTFontFamily {
public:
gfxMacFontFamily(const nsACString& aName, NSFont* aSystemFont)
: CTFontFamily(aName, FontVisibility::Unknown), mForSystemFont(aSystemFont) {
: CTFontFamily(aName, FontVisibility::Unknown),
mForSystemFont(aSystemFont) {
// I don't think the system font instance is at much risk of being deleted,
// but to be on the safe side let's retain a reference until we're finished
// using it for lazy initialization.
@ -88,9 +90,9 @@ class gfxMacFontFamily final : public CTFontFamily {
MOZ_REQUIRES(mLock) override;
protected:
// If non-null, this is a family representing the system UI font, and should use
// the given NSFont as the basis for initialization as the normal font-manager APIs
// based on family name won't handle it.
// If non-null, this is a family representing the system UI font, and should
// use the given NSFont as the basis for initialization as the normal
// font-manager APIs based on family name won't handle it.
NSFont* mForSystemFont = nullptr;
};
@ -99,7 +101,8 @@ void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
return;
}
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("gfxMacFontFamily::FindStyleVariations", LAYOUT, mName);
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("gfxMacFontFamily::FindStyleVariations",
LAYOUT, mName);
nsAutoreleasePool localPool;
@ -113,12 +116,14 @@ void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
nsCocoaUtils::GetStringForNSString(psNameNS, nameUTF16);
CopyUTF16toUTF8(nameUTF16, psName);
auto* fe = new CTFontEntry(psName, WeightRange(FontWeight::NORMAL), true, 0.0);
auto* fe =
new CTFontEntry(psName, WeightRange(FontWeight::NORMAL), true, 0.0);
// Set the appropriate style, assuming it may not have a variation range.
fe->mStyleRange = SlantStyleRange(
([[aNSFont fontDescriptor] symbolicTraits] & NSFontItalicTrait) ? FontSlantStyle::ITALIC
: FontSlantStyle::NORMAL);
([[aNSFont fontDescriptor] symbolicTraits] & NSFontItalicTrait)
? FontSlantStyle::ITALIC
: FontSlantStyle::NORMAL);
// Set up weight (and width, if present) ranges.
fe->SetupVariationRanges();
@ -128,7 +133,8 @@ void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
addToFamily(mForSystemFont);
// See if there is a corresponding italic face, and add it to the family.
NSFont* italicFont = [sFontManager convertFont:mForSystemFont toHaveTrait:NSItalicFontMask];
NSFont* italicFont = [sFontManager convertFont:mForSystemFont
toHaveTrait:NSItalicFontMask];
if (italicFont != mForSystemFont) {
addToFamily(italicFont);
}
@ -147,7 +153,8 @@ void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) {
class gfxSingleFaceMacFontFamily final : public gfxFontFamily {
public:
gfxSingleFaceMacFontFamily(const nsACString& aName, FontVisibility aVisibility)
gfxSingleFaceMacFontFamily(const nsACString& aName,
FontVisibility aVisibility)
: gfxFontFamily(aName, aVisibility) {
mFaceNamesInitialized = true; // omit from face name lists
}
@ -175,8 +182,9 @@ void gfxSingleFaceMacFontFamily::LocalizedName(nsACString& aLocalizedName) {
}
gfxFontEntry* fe = mAvailableFonts[0];
NSFont* font = [NSFont fontWithName:GetNSStringForString(NS_ConvertUTF8toUTF16(fe->Name()))
size:0.0];
NSFont* font = [NSFont
fontWithName:GetNSStringForString(NS_ConvertUTF8toUTF16(fe->Name()))
size:0.0];
if (font) {
NSString* localized = [font displayName];
if (localized) {
@ -191,7 +199,8 @@ void gfxSingleFaceMacFontFamily::LocalizedName(nsACString& aLocalizedName) {
aLocalizedName = mName;
}
void gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(gfxPlatformFontList* aPlatformFontList) {
void gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(
gfxPlatformFontList* aPlatformFontList) {
AutoWriteLock lock(mLock);
if (mOtherFamilyNamesInitialized) {
return;
@ -209,7 +218,8 @@ void gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(gfxPlatformFontList* aPlat
return;
}
mHasOtherFamilyNames = ReadOtherFamilyNamesForFace(aPlatformFontList, nameTable, true);
mHasOtherFamilyNames =
ReadOtherFamilyNamesForFace(aPlatformFontList, nameTable, true);
mOtherFamilyNamesInitialized = true;
}
@ -229,7 +239,8 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() : CoreTextFontList() {
gfxFontUtils::GetPrefsFontList("font.single-face-list", mSingleFaceFonts);
}
FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily(const nsACString& aName) const {
FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily(
const nsACString& aName) const {
if (aName[0] == '.' || aName.LowerCaseEqualsLiteral("lastresort")) {
return FontVisibility::Hidden;
}
@ -244,7 +255,8 @@ FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily(const nsACString&
return FontVisibility::User;
}
bool gfxMacPlatformFontList::DeprecatedFamilyIsAvailable(const nsACString& aName) {
bool gfxMacPlatformFontList::DeprecatedFamilyIsAvailable(
const nsACString& aName) {
NSString* family = GetNSStringForString(NS_ConvertUTF8toUTF16(aName));
return [[sFontManager availableMembersOfFontFamily:family] count] > 0;
}
@ -364,7 +376,8 @@ void gfxMacPlatformFontList::InitSingleFaceList() {
// We found the correct face, so create the single-face family record.
GenerateFontListKey(aliasName, key);
LOG_FONTLIST(("(fontlist-singleface) family name: %s, key: %s\n", aliasName.get(), key.get()));
LOG_FONTLIST(("(fontlist-singleface) family name: %s, key: %s\n",
aliasName.get(), key.get()));
// add only if doesn't exist already
if (!mFontFamilies.GetWeak(key)) {
@ -372,13 +385,14 @@ void gfxMacPlatformFontList::InitSingleFaceList() {
new gfxSingleFaceMacFontFamily(aliasName, family->Visibility());
// We need a separate font entry, because its family name will
// differ from the one we found in the main list.
CTFontEntry* fontEntry = new CTFontEntry(fe->Name(), fe->Weight(), true,
static_cast<const CTFontEntry*>(fe)->mSizeHint);
CTFontEntry* fontEntry =
new CTFontEntry(fe->Name(), fe->Weight(), true,
static_cast<const CTFontEntry*>(fe)->mSizeHint);
familyEntry->AddFontEntry(fontEntry);
familyEntry->SetHasStyles(true);
mFontFamilies.InsertOrUpdate(key, std::move(familyEntry));
LOG_FONTLIST(
("(fontlist-singleface) added new family: %s, key: %s\n", aliasName.get(), key.get()));
LOG_FONTLIST(("(fontlist-singleface) added new family: %s, key: %s\n",
aliasName.get(), key.get()));
}
}
}
@ -404,12 +418,14 @@ static NSString* GetRealFamilyName(NSFont* aFont) {
// Eventually we should move to using CTFontUIFontType constants to identify
// system fonts, and eliminate the need to instantiate them (indirectly) from
// their postscript names.
AutoCFRelease<CGFontRef> cgFont = CGFontCreateWithFontName(CFStringRef(psName));
AutoCFRelease<CGFontRef> cgFont =
CGFontCreateWithFontName(CFStringRef(psName));
if (!cgFont) {
return [aFont familyName];
}
AutoCFRelease<CTFontRef> ctFont = CTFontCreateWithGraphicsFont(cgFont, 0.0, nullptr, nullptr);
AutoCFRelease<CTFontRef> ctFont =
CTFontCreateWithGraphicsFont(cgFont, 0.0, nullptr, nullptr);
if (!ctFont) {
return [aFont familyName];
}
@ -441,7 +457,8 @@ void gfxMacPlatformFontList::InitSystemFontNames() {
// the hidden system fonts may be excluded from the font list altogether.
if (nsCocoaFeatures::OnCatalinaOrLater()) {
// This family will be populated based on the given NSFont.
RefPtr<gfxFontFamily> fam = new gfxMacFontFamily(mSystemTextFontFamilyName, sys);
RefPtr<gfxFontFamily> fam =
new gfxMacFontFamily(mSystemTextFontFamilyName, sys);
if (fam) {
nsAutoCString key;
GenerateFontListKey(mSystemTextFontFamilyName, key);
@ -465,20 +482,23 @@ void gfxMacPlatformFontList::InitSystemFontNames() {
// different system font API's always map to the same family under OSX, so
// just assume that and emit a warning if that ever changes
NSString* sysFamily = GetRealFamilyName([NSFont systemFontOfSize:0.0]);
if ([sysFamily compare:GetRealFamilyName([NSFont boldSystemFontOfSize:0.0])] != NSOrderedSame ||
[sysFamily compare:GetRealFamilyName([NSFont controlContentFontOfSize:0.0])] !=
if ([sysFamily compare:GetRealFamilyName([NSFont
boldSystemFontOfSize:0.0])] != NSOrderedSame ||
[sysFamily compare:GetRealFamilyName([NSFont
controlContentFontOfSize:0.0])] != NSOrderedSame ||
[sysFamily compare:GetRealFamilyName([NSFont menuBarFontOfSize:0.0])] !=
NSOrderedSame ||
[sysFamily compare:GetRealFamilyName([NSFont menuBarFontOfSize:0.0])] != NSOrderedSame ||
[sysFamily compare:GetRealFamilyName([NSFont toolTipsFontOfSize:0.0])] != NSOrderedSame) {
[sysFamily compare:GetRealFamilyName([NSFont toolTipsFontOfSize:0.0])] !=
NSOrderedSame) {
NS_WARNING("system font types map to different font families"
" -- please log a bug!!");
}
#endif
}
FontFamily gfxMacPlatformFontList::GetDefaultFontForPlatform(nsPresContext* aPresContext,
const gfxFontStyle* aStyle,
nsAtom* aLanguage) {
FontFamily gfxMacPlatformFontList::GetDefaultFontForPlatform(
nsPresContext* aPresContext, const gfxFontStyle* aStyle,
nsAtom* aLanguage) {
nsAutoreleasePool localPool;
NSString* defaultFamily = [[NSFont userFontOfSize:aStyle->size] familyName];
@ -538,11 +558,14 @@ void gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID,
}
NSFontSymbolicTraits traits = [[font fontDescriptor] symbolicTraits];
aFontStyle.style = (traits & NSFontItalicTrait) ? FontSlantStyle::ITALIC : FontSlantStyle::NORMAL;
aFontStyle.weight = (traits & NSFontBoldTrait) ? FontWeight::BOLD : FontWeight::NORMAL;
aFontStyle.stretch = (traits & NSFontExpandedTrait) ? FontStretch::EXPANDED
: (traits & NSFontCondensedTrait) ? FontStretch::CONDENSED
: FontStretch::NORMAL;
aFontStyle.style = (traits & NSFontItalicTrait) ? FontSlantStyle::ITALIC
: FontSlantStyle::NORMAL;
aFontStyle.weight =
(traits & NSFontBoldTrait) ? FontWeight::BOLD : FontWeight::NORMAL;
aFontStyle.stretch = (traits & NSFontExpandedTrait) ? FontStretch::EXPANDED
: (traits & NSFontCondensedTrait)
? FontStretch::CONDENSED
: FontStretch::NORMAL;
aFontStyle.size = [font pointSize];
aFontStyle.systemFont = true;
}

Просмотреть файл

@ -21,7 +21,8 @@ static io_connect_t sDataPort = IO_OBJECT_NULL;
static uint64_t sLastMean = -1;
static float LMUvalueToLux(uint64_t aValue) {
// Conversion formula from regression. See Bug 793728.
// -3*(10^-27)*x^4 + 2.6*(10^-19)*x^3 + -3.4*(10^-12)*x^2 + 3.9*(10^-5)*x - 0.19
// -3*(10^-27)*x^4 + 2.6*(10^-19)*x^3 + -3.4*(10^-12)*x^2 + 3.9*(10^-5)*x -
// 0.19
long double powerC4 = 1 / pow((long double)10, 27);
long double powerC3 = 1 / pow((long double)10, 19);
long double powerC2 = 1 / pow((long double)10, 12);
@ -54,7 +55,8 @@ void UpdateHandler(nsITimer* aTimer, void* aClosure) {
uint32_t outputs = 2;
uint64_t lightLMU[outputs];
kr = IOConnectCallMethod(sDataPort, 0, nil, 0, nil, 0, lightLMU, &outputs, nil, 0);
kr = IOConnectCallMethod(sDataPort, 0, nil, 0, nil, 0, lightLMU, &outputs,
nil, 0);
if (kr == KERN_SUCCESS) {
uint64_t mean = (lightLMU[0] + lightLMU[1]) / 2;
if (mean == sLastMean) {
@ -84,8 +86,8 @@ void EnableSensorNotifications(SensorType aSensor) {
}
} else if (aSensor == SENSOR_LIGHT) {
io_service_t serviceObject;
serviceObject =
IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController"));
serviceObject = IOServiceGetMatchingService(
kIOMasterPortDefault, IOServiceMatching("AppleLMUController"));
if (!serviceObject) {
return;
}
@ -104,14 +106,15 @@ void EnableSensorNotifications(SensorType aSensor) {
if (!sUpdateTimer) {
CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
if (sUpdateTimer) {
sUpdateTimer->InitWithNamedFuncCallback(UpdateHandler, nullptr, DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK,
"hal_impl::UpdateHandler");
sUpdateTimer->InitWithNamedFuncCallback(
UpdateHandler, nullptr, DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK, "hal_impl::UpdateHandler");
}
}
}
void DisableSensorNotifications(SensorType aSensor) {
if (!sActiveSensors[aSensor] || (aSensor != SENSOR_ACCELERATION && aSensor != SENSOR_LIGHT)) {
if (!sActiveSensors[aSensor] ||
(aSensor != SENSOR_ACCELERATION && aSensor != SENSOR_LIGHT)) {
return;
}

Просмотреть файл

@ -80,20 +80,21 @@ typedef struct sensorSpec {
//
// These values came from SeisMaCalibrate calibration reports. In general I've
// found the following:
// - All Intel-based SMSs have 250 counts per g, centered on 0, but the signs
// are different (and in one case two axes are swapped)
// - All Intel-based SMSs have 250 counts per g, centered on 0, but the
// signs are different (and in one case two axes are swapped)
// - PowerBooks and iBooks all have sensors centered on 0, and reading
// 50-53 steps per gravity (but with differing polarities!)
// - PowerBooks and iBooks of the same model all have the same axis polarities
// - PowerBooks and iBooks of the same model all have the same axis
// polarities
// - PowerBook and iBook access methods are model- and OS version-specific
//
// So, the sequence of tests is:
// - Try model-specific access methods. Note that the test is for a match to the
// beginning of the model name, e.g. the record with model name "MacBook"
// matches computer models "MacBookPro1,2" and "MacBook1,1" (and ""
// - Try model-specific access methods. Note that the test is for a match
// to the beginning of the model name, e.g. the record with model name
// "MacBook" matches computer models "MacBookPro1,2" and "MacBook1,1" (and ""
// matches any model).
// - If no model-specific record's access fails, then try each model-independent
// access method in order, stopping when one works.
// - If no model-specific record's access fails, then try each
// model-independent access method in order, stopping when one works.
static const sensorSpec sensors[] = {
// ****** Model-dependent methods ******
// The PowerBook5,6 is one of the G4 models that seems to lose
@ -142,7 +143,8 @@ static const sensorSpec sensors[] = {
5,
40,
{{1, 0, 2, 0, 251}, {1, 2, 2, 0, -251}, {1, 4, 2, 0, -251}}},
// MacBook Pro Core 2 Duo 15" AND 17" with LED backlight, introduced June '07.
// MacBook Pro Core 2 Duo 15" AND 17" with LED backlight, introduced June
// '07.
// NOTE! The 17" machines have the signs of their X and Y axes reversed
// from this calibration, but there's no clear way to discriminate between
// the two machines.
@ -169,7 +171,8 @@ static const sensorSpec sensors[] = {
5,
40,
{{1, 0, 2, 0, -251}, {1, 2, 2, 0, -251}, {1, 4, 2, 0, 251}}},
// This is speculative, based on a single user's report. Looks like the X and Y axes
// This is speculative, based on a single user's report. Looks like the X
// and Y axes
// are swapped. This is true for no other known Appple laptop.
{"MacBookPro5,3",
"SMCMotionSensor",
@ -185,10 +188,18 @@ static const sensorSpec sensors[] = {
// ****** Model-independent methods ******
// Seen once with PowerBook6,8 under system 10.3.9; I suspect
// other G4-based 10.3.* systems might use this
{"", "IOI2CMotionSensor", 24, 60, {{1, 0, 1, 0, 51.5}, {1, 1, 1, 0, 51.5}, {1, 2, 1, 0, 51.5}}},
{"",
"IOI2CMotionSensor",
24,
60,
{{1, 0, 1, 0, 51.5}, {1, 1, 1, 0, 51.5}, {1, 2, 1, 0, 51.5}}},
// PowerBook5,6 , PowerBook5,7 , PowerBook6,7 , PowerBook6,8
// under OS X 10.4.*
{"", "IOI2CMotionSensor", 21, 60, {{1, 0, 1, 0, 51.5}, {1, 1, 1, 0, 51.5}, {1, 2, 1, 0, 51.5}}},
{"",
"IOI2CMotionSensor",
21,
60,
{{1, 0, 1, 0, 51.5}, {1, 1, 1, 0, 51.5}, {1, 2, 1, 0, 51.5}}},
// PowerBook5,8 , PowerBook5,9 under OS X 10.4.*
{"",
"PMUMotionSensor",
@ -200,9 +211,11 @@ static const sensorSpec sensors[] = {
{1, 0, 1, 0, -51.5},
{1, 1, 1, -6, -51.5},
{1, 2, 1, 0, -51.5}}},
// All MacBook, MacBookPro models. Hardware (at least on early MacBookPro 15")
// All MacBook, MacBookPro models. Hardware (at least on early MacBookPro
// 15")
// is Kionix KXM52-1050 three-axis accelerometer chip. Data is at
// http://kionix.com/Product-Index/product-index.htm. Specific MB and MBP models
// http://kionix.com/Product-Index/product-index.htm. Specific MB and MBP
// models
// that use this are:
// MacBook1,1
// MacBook2,1
@ -215,13 +228,18 @@ static const sensorSpec sensors[] = {
// MacBookPro1,2
// MacBookPro4,1
// MacBookPro5,5
{"", "SMCMotionSensor", 5, 40, {{1, 0, 2, 0, 251}, {1, 2, 2, 0, 251}, {1, 4, 2, 0, 251}}}};
{"",
"SMCMotionSensor",
5,
40,
{{1, 0, 2, 0, 251}, {1, 2, 2, 0, 251}, {1, 4, 2, 0, 251}}}};
#define SENSOR_COUNT (sizeof(sensors) / sizeof(sensorSpec))
#pragma mark Internal prototypes
static int getData(sms_acceleration* accel, int calibrated, id logObject, SEL logSelector);
static int getData(sms_acceleration* accel, int calibrated, id logObject,
SEL logSelector);
static float getAxis(int which, int calibrated);
static int signExtend(int value, int size);
static NSString* getModelName(void);
@ -259,7 +277,8 @@ static float onegs[3]; // X, Y and Z one-g calibration values
// Name of configuration for given axis' zero (axis specified by integer)
#define ZERO_NAME(a) [NSString stringWithFormat:@"%@-Axis-Zero", INT_TO_AXIS(a)]
// Name of configuration for given axis' oneg (axis specified by integer)
#define ONEG_NAME(a) [NSString stringWithFormat:@"%@-Axis-One-g", INT_TO_AXIS(a)]
#define ONEG_NAME(a) \
[NSString stringWithFormat:@"%@-Axis-One-g", INT_TO_AXIS(a)]
// Name of "Is calibrated" preference
#define CALIBRATED_NAME (@"Calibrated")
// Application domain for SeisMac library
@ -271,19 +290,22 @@ static float onegs[3]; // X, Y and Z one-g calibration values
if (logObject) { \
[logObject performSelector:logSelector withObject:message]; \
}
#define LOG_ARG(format, var1) \
if (logObject) { \
[logObject performSelector:logSelector withObject:[NSString stringWithFormat:format, var1]]; \
#define LOG_ARG(format, var1) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1]]; \
}
#define LOG_2ARG(format, var1, var2) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2]]; \
#define LOG_2ARG(format, var1, var2) \
if (logObject) { \
[logObject \
performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2]]; \
}
#define LOG_3ARG(format, var1, var2, var3) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2, var3]]; \
#define LOG_3ARG(format, var1, var2, var3) \
if (logObject) { \
[logObject \
performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2, var3]]; \
}
#pragma mark Function definitions
@ -322,11 +344,12 @@ int smsStartup(id logObject, SEL logSelector) {
recordSize = sensors[sensorNum].recordSize;
function = sensors[sensorNum].function;
LOG_3ARG(@"Trying service \"%s\" with selector %d and %d byte record:\n", serviceName, function,
recordSize);
LOG_3ARG(@"Trying service \"%s\" with selector %d and %d byte record:\n",
serviceName, function, recordSize);
NSString* targetName = [NSString stringWithCString:sensors[sensorNum].model
encoding:NSMacOSRomanStringEncoding];
NSString* targetName =
[NSString stringWithCString:sensors[sensorNum].model
encoding:NSMacOSRomanStringEncoding];
LOG_ARG(@" Comparing model name to target \"%@\": ", targetName);
if ([targetName length] == 0 || [modelName hasPrefix:targetName]) {
LOG(@"success.\n");
@ -350,7 +373,8 @@ int smsStartup(id logObject, SEL logSelector) {
}
LOG(@" Getting list of matching services: ");
result = IOServiceGetMatchingServices(kIOMasterPortDefault, dict, &iterator);
result =
IOServiceGetMatchingServices(kIOMasterPortDefault, dict, &iterator);
if (result == KERN_SUCCESS) {
LOG(@"success.\n");
@ -386,7 +410,9 @@ int smsStartup(id logObject, SEL logSelector) {
}
continue;
} else if (connection == 0) {
LOG_ARG(@"'success', but didn't get a connection (return value was: 0x%x).\n", result);
LOG_ARG(
@"'success', but didn't get a connection (return value was: 0x%x).\n",
result);
IOObjectRelease(device);
if (failure_result < SMS_FAIL_CONNECTION) {
failure_result = SMS_FAIL_CONNECTION;
@ -551,14 +577,15 @@ void smsGetBufferData(char* buffer) {
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
const size_t InStructSize = recordSize;
size_t OutStructSize = recordSize;
result =
IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void*)iRecord, InStructSize, (void*)buffer, &OutStructSize);
result = IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void*)iRecord, InStructSize,
(void*)buffer, &OutStructSize);
#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
result = IOConnectMethodStructureIStructureO(connection,
function, // magic kernel function number
iSize, &oSize, iRecord, buffer);
result = IOConnectMethodStructureIStructureO(
connection,
function, // magic kernel function number
iSize, &oSize, iRecord, buffer);
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
if (result != KERN_SUCCESS) {
@ -580,9 +607,10 @@ NSString* smsGetCalibrationDescription(void) {
[s appendString:@"---- SeisMac Calibration Record ----\n \n"];
[s appendFormat:@"Machine model: %@\n", getModelName()];
[s appendFormat:@"OS X build: %@\n", getOSVersion()];
[s appendFormat:@"SeisMacLib version %s, record %d\n \n", SMSLIB_VERSION, sensorNum];
[s appendFormat:@"Using service \"%s\", function index %d, size %d\n \n", serviceName, function,
recordSize];
[s appendFormat:@"SeisMacLib version %s, record %d\n \n", SMSLIB_VERSION,
sensorNum];
[s appendFormat:@"Using service \"%s\", function index %d, size %d\n \n",
serviceName, function, recordSize];
if (prefIntRead(CALIBRATED_NAME, &success) && success) {
[s appendString:@"Calibration values (from calibration):\n"];
} else {
@ -670,7 +698,8 @@ static void deleteCalibration(void) {
static float prefFloatRead(NSString* prefName, BOOL* success) {
float result = 0.0f;
CFPropertyListRef ref = CFPreferencesCopyAppValue((CFStringRef)prefName, APP_ID);
CFPropertyListRef ref =
CFPreferencesCopyAppValue((CFStringRef)prefName, APP_ID);
// If there isn't such a preference, fail
if (ref == NULL) {
*success = NO;
@ -682,7 +711,8 @@ static float prefFloatRead(NSString* prefName, BOOL* success) {
// Is it a floating point number?
if (CFNumberIsFloatType((CFNumberRef)ref)) {
// Yup: grab it.
*success = CFNumberGetValue((__CFNumber*)ref, kCFNumberFloat32Type, &result);
*success =
CFNumberGetValue((__CFNumber*)ref, kCFNumberFloat32Type, &result);
} else {
// Nope: grab as an integer, and convert to a float.
long num;
@ -707,7 +737,8 @@ static float prefFloatRead(NSString* prefName, BOOL* success) {
// Writes a named floating point value to the stored preferences.
static void prefFloatWrite(NSString* prefName, float prefValue) {
CFNumberRef cfFloat = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &prefValue);
CFNumberRef cfFloat =
CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &prefValue);
CFPreferencesSetAppValue((CFStringRef)prefName, cfFloat, APP_ID);
CFRelease(cfFloat);
}
@ -715,7 +746,8 @@ static void prefFloatWrite(NSString* prefName, float prefValue) {
// Reads a named integer value from the stored preferences.
static int prefIntRead(NSString* prefName, BOOL* success) {
Boolean internalSuccess;
CFIndex result = CFPreferencesGetAppIntegerValue((CFStringRef)prefName, APP_ID, &internalSuccess);
CFIndex result = CFPreferencesGetAppIntegerValue((CFStringRef)prefName,
APP_ID, &internalSuccess);
*success = internalSuccess;
return result;
@ -723,7 +755,8 @@ static int prefIntRead(NSString* prefName, BOOL* success) {
// Writes a named integer value to the stored preferences.
static void prefIntWrite(NSString* prefName, int prefValue) {
CFPreferencesSetAppValue((CFStringRef)prefName, (CFNumberRef)[NSNumber numberWithInt:prefValue],
CFPreferencesSetAppValue((CFStringRef)prefName,
(CFNumberRef)[NSNumber numberWithInt:prefValue],
APP_ID);
}
@ -736,7 +769,8 @@ static void prefDelete(NSString* prefName) {
static void prefSynchronize(void) { CFPreferencesAppSynchronize(APP_ID); }
// Internal version of accelGetData, with logging
int getData(sms_acceleration* accel, int calibrated, id logObject, SEL logSelector) {
int getData(sms_acceleration* accel, int calibrated, id logObject,
SEL logSelector) {
IOItemCount iSize = recordSize;
IOByteCount oSize = recordSize;
kern_return_t result;
@ -754,14 +788,15 @@ int getData(sms_acceleration* accel, int calibrated, id logObject, SEL logSelect
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
const size_t InStructSize = recordSize;
size_t OutStructSize = recordSize;
result =
IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void*)iRecord, InStructSize, (void*)oRecord, &OutStructSize);
result = IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void*)iRecord, InStructSize,
(void*)oRecord, &OutStructSize);
#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
result = IOConnectMethodStructureIStructureO(connection,
function, // magic kernel function number
iSize, &oSize, iRecord, oRecord);
result = IOConnectMethodStructureIStructureO(
connection,
function, // magic kernel function number
iSize, &oSize, iRecord, oRecord);
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
if (result != KERN_SUCCESS) {
@ -845,11 +880,13 @@ NSString* getModelName(void) {
// Returns the current OS X version and build (e.g. "10.4.7 (build 8J2135a)")
NSString* getOSVersion(void) {
NSDictionary* dict = [NSDictionary
dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
NSDictionary* dict =
[NSDictionary dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"];
NSString* versionString = [dict objectForKey:@"ProductVersion"];
NSString* buildString = [dict objectForKey:@"ProductBuildVersion"];
NSString* wholeString = [NSString stringWithFormat:@"%@ (build %@)", versionString, buildString];
NSString* wholeString =
[NSString stringWithFormat:@"%@ (build %@)", versionString, buildString];
return wholeString;
}

Просмотреть файл

@ -42,7 +42,8 @@ nsIconChannel::~nsIconChannel() {
}
}
NS_IMPL_ISUPPORTS(nsIconChannel, nsIChannel, nsIRequest, nsIRequestObserver, nsIStreamListener)
NS_IMPL_ISUPPORTS(nsIconChannel, nsIChannel, nsIRequest, nsIRequestObserver,
nsIStreamListener)
nsresult nsIconChannel::Init(nsIURI* uri) {
NS_ASSERTION(uri, "no uri");
@ -73,7 +74,8 @@ NS_IMETHODIMP nsIconChannel::GetCanceledReason(nsACString& aReason) {
return GetCanceledReasonImpl(aReason);
}
NS_IMETHODIMP nsIconChannel::CancelWithReason(nsresult aStatus, const nsACString& aReason) {
NS_IMETHODIMP nsIconChannel::CancelWithReason(nsresult aStatus,
const nsACString& aReason) {
return CancelWithReasonImpl(aStatus, aReason);
}
@ -121,8 +123,8 @@ nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
// nsIStreamListener methods
NS_IMETHODIMP
nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream, uint64_t aOffset,
uint32_t aCount) {
nsIconChannel::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
uint64_t aOffset, uint32_t aCount) {
if (mListener) {
return mListener->OnDataAvailable(this, aStream, aOffset, aCount);
}
@ -156,13 +158,15 @@ nsIconChannel::GetURI(nsIURI** aURI) {
NS_IMETHODIMP
nsIconChannel::Open(nsIInputStream** _retval) {
nsCOMPtr<nsIStreamListener> listener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
nsresult rv =
nsContentSecurityManager::doContentSecurityCheck(this, listener);
NS_ENSURE_SUCCESS(rv, rv);
return MakeInputStream(_retval, false);
}
nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile, uint32_t* aDesiredImageSize,
nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile,
uint32_t* aDesiredImageSize,
nsACString& aContentType,
nsACString& aFileExtension) {
nsresult rv = NS_OK;
@ -196,18 +200,21 @@ nsresult nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile, uint32_t* a
NS_IMETHODIMP
nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
nsCOMPtr<nsIStreamListener> listener = aListener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
nsresult rv =
nsContentSecurityManager::doContentSecurityCheck(this, listener);
if (NS_FAILED(rv)) {
mCallbacks = nullptr;
return rv;
}
MOZ_ASSERT(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() ||
(mLoadInfo->GetSecurityMode() ==
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&
mLoadInfo->GetLoadingPrincipal() &&
mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),
"security flags in loadInfo but doContentSecurityCheck() not called");
MOZ_ASSERT(
mLoadInfo->GetSecurityMode() == 0 ||
mLoadInfo->GetInitialSecurityCheckDone() ||
(mLoadInfo->GetSecurityMode() ==
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&
mLoadInfo->GetLoadingPrincipal() &&
mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),
"security flags in loadInfo but doContentSecurityCheck() not called");
nsCOMPtr<nsIInputStream> inStream;
rv = MakeInputStream(getter_AddRefs(inStream), true);
@ -218,7 +225,8 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
// Init our stream pump
nsCOMPtr<nsISerialEventTarget> target =
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo, mozilla::TaskCategory::Other);
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
mozilla::TaskCategory::Other);
rv = mPump->Init(inStream, 0, 0, false, target);
if (NS_FAILED(rv)) {
mCallbacks = nullptr;
@ -240,15 +248,16 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener) {
return rv;
}
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlocking) {
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval,
bool aNonBlocking) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsCString contentType;
nsAutoCString fileExt;
nsCOMPtr<nsIFile> fileloc; // file we want an icon for
uint32_t desiredImageSize;
nsresult rv =
ExtractIconInfoFromUrl(getter_AddRefs(fileloc), &desiredImageSize, contentType, fileExt);
nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(fileloc),
&desiredImageSize, contentType, fileExt);
NS_ENSURE_SUCCESS(rv, rv);
bool fileExists = false;
@ -265,7 +274,8 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlock
CFURLRef macURL;
if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
iconImage = [[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
iconImage =
[[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
::CFRelease(macURL);
}
}
@ -278,7 +288,8 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlock
// If we still don't have an icon, get the generic document icon.
if (!iconImage) {
iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeUnknown];
iconImage =
[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeUnknown];
}
if (!iconImage) {
@ -296,8 +307,10 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlock
// account when it requests these icons; e.g. it will request an icon with
// size 16, place it in a 16x16 CSS pixel sized image, and then display it in
// a window on a HiDPI screen where the icon now covers 32x32 physical screen
// pixels. So we just always double the size here in order to prevent blurriness.
uint32_t size = (desiredImageSize < 128) ? desiredImageSize * 2 : desiredImageSize;
// pixels. So we just always double the size here in order to prevent
// blurriness.
uint32_t size =
(desiredImageSize < 128) ? desiredImageSize * 2 : desiredImageSize;
uint32_t width = size;
uint32_t height = size;
@ -322,14 +335,15 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlock
// This gives us the image data in the format we want: BGRA, four bytes per
// pixel, in host endianness, with premultiplied alpha.
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx =
CGBitmapContextCreate(imageBuf, width, height, 8 /* bitsPerComponent */, width * 4, cs,
kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
CGContextRef ctx = CGBitmapContextCreate(
imageBuf, width, height, 8 /* bitsPerComponent */, width * 4, cs,
kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(cs);
NSGraphicsContext* oldContext = [NSGraphicsContext currentContext];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx
flipped:NO]];
[NSGraphicsContext
setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx
flipped:NO]];
[iconImage drawInRect:NSMakeRect(0, 0, width, height)];
@ -340,8 +354,8 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, bool aNonBlock
// Now, create a pipe and stuff our data into it
nsCOMPtr<nsIInputStream> inStream;
nsCOMPtr<nsIOutputStream> outStream;
NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), bufferCapacity, bufferCapacity,
aNonBlocking);
NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream),
bufferCapacity, bufferCapacity, aNonBlocking);
uint32_t written;
rv = outStream->Write((char*)fileBuf.get(), bufferCapacity, &written);
@ -368,10 +382,14 @@ nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes) {
}
NS_IMETHODIMP
nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) { return GetTRRModeImpl(aTRRMode); }
nsIconChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
return GetTRRModeImpl(aTRRMode);
}
NS_IMETHODIMP
nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) { return SetTRRModeImpl(aTRRMode); }
nsIconChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
return SetTRRModeImpl(aTRRMode);
}
NS_IMETHODIMP
nsIconChannel::GetIsDocument(bool* aIsDocument) {
@ -415,17 +433,20 @@ nsIconChannel::SetContentDisposition(uint32_t aContentDisposition) {
}
NS_IMETHODIMP
nsIconChannel::GetContentDispositionFilename(nsAString& aContentDispositionFilename) {
nsIconChannel::GetContentDispositionFilename(
nsAString& aContentDispositionFilename) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::SetContentDispositionFilename(const nsAString& aContentDispositionFilename) {
nsIconChannel::SetContentDispositionFilename(
const nsAString& aContentDispositionFilename) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsIconChannel::GetContentDispositionHeader(nsACString& aContentDispositionHeader) {
nsIconChannel::GetContentDispositionHeader(
nsACString& aContentDispositionHeader) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -481,14 +502,16 @@ nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
}
NS_IMETHODIMP
nsIconChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aNotificationCallbacks) {
nsIconChannel::GetNotificationCallbacks(
nsIInterfaceRequestor** aNotificationCallbacks) {
*aNotificationCallbacks = mCallbacks.get();
NS_IF_ADDREF(*aNotificationCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsIconChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) {
nsIconChannel::SetNotificationCallbacks(
nsIInterfaceRequestor* aNotificationCallbacks) {
mCallbacks = aNotificationCallbacks;
return NS_OK;
}

Просмотреть файл

@ -7,7 +7,8 @@
#include "base/logging.h"
@interface CrApplication ()
@property(readwrite, getter=isHandlingSendEvent, nonatomic) BOOL handlingSendEvent;
@property(readwrite, getter=isHandlingSendEvent, nonatomic)
BOOL handlingSendEvent;
@end
@implementation CrApplication
@ -19,7 +20,8 @@
+ (NSApplication*)sharedApplication {
NSApplication* app = [super sharedApplication];
if (![NSApp isKindOfClass:self]) {
CHROMIUM_LOG(ERROR) << "NSApp should be of type " << [[self className] UTF8String] << ", not "
CHROMIUM_LOG(ERROR) << "NSApp should be of type "
<< [[self className] UTF8String] << ", not "
<< [[NSApp className] UTF8String];
DCHECK(false) << "NSApp is of wrong type";
}
@ -59,6 +61,8 @@ ScopedSendingEvent::ScopedSendingEvent()
[app_ setHandlingSendEvent:YES];
}
ScopedSendingEvent::~ScopedSendingEvent() { [app_ setHandlingSendEvent:handling_]; }
ScopedSendingEvent::~ScopedSendingEvent() {
[app_ setHandlingSendEvent:handling_];
}
} // namespace chrome_application_mac

Просмотреть файл

@ -22,7 +22,8 @@ bool AmIBundled() {
if (GetProcessBundleLocation(&psn, &fsref) != noErr) return false;
FSCatalogInfo info;
if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info, NULL, NULL, NULL) != noErr) {
if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info, NULL, NULL, NULL) !=
noErr) {
return false;
}

Просмотреть файл

@ -19,7 +19,8 @@ namespace {
void NoOp(void* info) {}
const CFTimeInterval kCFTimeIntervalMax = std::numeric_limits<CFTimeInterval>::max();
const CFTimeInterval kCFTimeIntervalMax =
std::numeric_limits<CFTimeInterval>::max();
} // namespace
@ -57,12 +58,13 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
// as needed when ScheduleDelayedWork is called.
CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
timer_context.info = this;
delayed_work_timer_ = CFRunLoopTimerCreate(NULL, // allocator
kCFTimeIntervalMax, // fire time
kCFTimeIntervalMax, // interval
0, // flags
0, // priority
RunDelayedWorkTimer, &timer_context);
delayed_work_timer_ =
CFRunLoopTimerCreate(NULL, // allocator
kCFTimeIntervalMax, // fire time
kCFTimeIntervalMax, // interval
0, // flags
0, // priority
RunDelayedWorkTimer, &timer_context);
CFRunLoopAddTimer(run_loop_, delayed_work_timer_, kCFRunLoopCommonModes);
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
@ -89,36 +91,42 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
0, // priority
&source_context);
CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_, kCFRunLoopCommonModes);
CFRunLoopAddSource(run_loop_, nesting_deferred_work_source_,
kCFRunLoopCommonModes);
CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
observer_context.info = this;
pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeWaiting,
true, // repeat
0, // priority
PreWaitObserver, &observer_context);
pre_wait_observer_ =
CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeWaiting,
true, // repeat
0, // priority
PreWaitObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeSources,
true, // repeat
0, // priority
PreSourceObserver, &observer_context);
pre_source_observer_ =
CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopBeforeSources,
true, // repeat
0, // priority
PreSourceObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, pre_source_observer_, kCFRunLoopCommonModes);
enter_exit_observer_ = CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopEntry | kCFRunLoopExit,
true, // repeat
0, // priority
EnterExitObserver, &observer_context);
enter_exit_observer_ =
CFRunLoopObserverCreate(NULL, // allocator
kCFRunLoopEntry | kCFRunLoopExit,
true, // repeat
0, // priority
EnterExitObserver, &observer_context);
CFRunLoopAddObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
root_power_domain_ = IORegisterForSystemPower(
this, &power_notification_port_, PowerStateNotification, &power_notification_object_);
root_power_domain_ = IORegisterForSystemPower(this, &power_notification_port_,
PowerStateNotification,
&power_notification_object_);
if (root_power_domain_ != MACH_PORT_NULL) {
CFRunLoopAddSource(run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
CFRunLoopAddSource(
run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
}
}
@ -127,23 +135,27 @@ MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
// same number of run loops must be running when this object is destroyed.
MessagePumpCFRunLoopBase::~MessagePumpCFRunLoopBase() {
if (root_power_domain_ != MACH_PORT_NULL) {
CFRunLoopRemoveSource(run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
CFRunLoopRemoveSource(
run_loop_, IONotificationPortGetRunLoopSource(power_notification_port_),
kCFRunLoopCommonModes);
IODeregisterForSystemPower(&power_notification_object_);
IOServiceClose(root_power_domain_);
IONotificationPortDestroy(power_notification_port_);
}
CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_, kCFRunLoopCommonModes);
CFRunLoopRemoveObserver(run_loop_, enter_exit_observer_,
kCFRunLoopCommonModes);
CFRelease(enter_exit_observer_);
CFRunLoopRemoveObserver(run_loop_, pre_source_observer_, kCFRunLoopCommonModes);
CFRunLoopRemoveObserver(run_loop_, pre_source_observer_,
kCFRunLoopCommonModes);
CFRelease(pre_source_observer_);
CFRunLoopRemoveObserver(run_loop_, pre_wait_observer_, kCFRunLoopCommonModes);
CFRelease(pre_wait_observer_);
CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_, kCFRunLoopCommonModes);
CFRunLoopRemoveSource(run_loop_, nesting_deferred_work_source_,
kCFRunLoopCommonModes);
CFRelease(nesting_deferred_work_source_);
CFRunLoopRemoveSource(run_loop_, idle_work_source_, kCFRunLoopCommonModes);
@ -203,7 +215,8 @@ void MessagePumpCFRunLoopBase::ScheduleWork() {
}
// Must be called on the run loop thread.
void MessagePumpCFRunLoopBase::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
const TimeTicks& delayed_work_time) {
TimeDelta delta = delayed_work_time - TimeTicks::Now();
delayed_work_fire_time_ = CFAbsoluteTimeGetCurrent() + delta.InSecondsF();
CFRunLoopTimerSetNextFireDate(delayed_work_timer_, delayed_work_fire_time_);
@ -211,7 +224,8 @@ void MessagePumpCFRunLoopBase::ScheduleDelayedWork(const TimeTicks& delayed_work
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer, void* info) {
void MessagePumpCFRunLoopBase::RunDelayedWorkTimer(CFRunLoopTimerRef timer,
void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// The timer won't fire again until it's reset.
@ -392,7 +406,8 @@ void MessagePumpCFRunLoopBase::MaybeScheduleNestingDeferredWork() {
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity, void* info) {
CFRunLoopActivity activity,
void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// Attempt to do some idle work before going to sleep.
@ -408,7 +423,8 @@ void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity, void* info) {
CFRunLoopActivity activity,
void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
// The run loop has reached the top of the loop and is about to begin
@ -422,7 +438,8 @@ void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
CFRunLoopActivity activity, void* info) {
CFRunLoopActivity activity,
void* info) {
MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
switch (activity) {
@ -463,7 +480,8 @@ void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
// Called from the run loop.
// static
void MessagePumpCFRunLoopBase::PowerStateNotification(void* info, io_service_t service,
void MessagePumpCFRunLoopBase::PowerStateNotification(void* info,
io_service_t service,
uint32_t message_type,
void* message_argument) {
// CFRunLoopTimer (NSTimer) is scheduled in terms of CFAbsoluteTime, which
@ -508,7 +526,8 @@ void MessagePumpCFRunLoopBase::PowerStateNotification(void* info, io_service_t s
switch (message_type) {
case kIOMessageSystemWillPowerOn:
if (self->delayed_work_fire_time_ != kCFTimeIntervalMax) {
CFRunLoopTimerSetNextFireDate(self->delayed_work_timer_, self->delayed_work_fire_time_);
CFRunLoopTimerSetNextFireDate(self->delayed_work_timer_,
self->delayed_work_fire_time_);
}
break;
@ -517,7 +536,8 @@ void MessagePumpCFRunLoopBase::PowerStateNotification(void* info, io_service_t s
// The system will wait for 30 seconds before entering sleep if neither
// IOAllowPowerChange nor IOCancelPowerChange are called. That would be
// pretty antisocial.
IOAllowPowerChange(self->root_power_domain_, reinterpret_cast<long>(message_argument));
IOAllowPowerChange(self->root_power_domain_,
reinterpret_cast<long>(message_argument));
break;
default:
@ -546,7 +566,8 @@ void MessagePumpCFRunLoop::DoRun(Delegate* delegate) {
int result;
do {
MessagePumpScopedAutoreleasePool autorelease_pool(this);
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalMax, false);
result =
CFRunLoopRunInMode(kCFRunLoopDefaultMode, kCFTimeIntervalMax, false);
} while (result != kCFRunLoopRunStopped && result != kCFRunLoopRunFinished);
}
@ -568,7 +589,8 @@ void MessagePumpCFRunLoop::Quit() {
// Called by MessagePumpCFRunLoopBase::EnterExitObserver.
void MessagePumpCFRunLoop::EnterExitRunLoop(CFRunLoopActivity activity) {
if (activity == kCFRunLoopExit && nesting_level() == run_nesting_level() && quit_pending_) {
if (activity == kCFRunLoopExit && nesting_level() == run_nesting_level() &&
quit_pending_) {
// Quit was called while loops other than those managed by this object
// were running further inside a run loop managed by this object. Now
// that all unmanaged inner run loops are gone, stop the loop running
@ -595,7 +617,8 @@ MessagePumpNSRunLoop::~MessagePumpNSRunLoop() {
void MessagePumpNSRunLoop::DoRun(Delegate* delegate) {
while (keep_running_) {
// NSRunLoop manages autorelease pools itself.
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
}
keep_running_ = true;

Просмотреть файл

@ -42,7 +42,9 @@ void InitThreading() {
static BOOL multithreaded = [NSThread isMultiThreaded];
if (!multithreaded) {
[NSThread detachNewThreadSelector:@selector(noOp) toTarget:[NoOp class] withObject:nil];
[NSThread detachNewThreadSelector:@selector(noOp)
toTarget:[NoOp class]
withObject:nil];
multithreaded = YES;
DCHECK([NSThread isMultiThreaded]);

Просмотреть файл

@ -41,7 +41,8 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
namespace base {
Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
const LaunchOptions& options, ProcessHandle* process_handle) {
const LaunchOptions& options,
ProcessHandle* process_handle) {
Result<Ok, LaunchError> retval = Ok();
char* argv_copy[argv.size() + 1];
@ -52,7 +53,8 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
EnvironmentArray env_storage;
const EnvironmentArray& vars =
options.full_env ? options.full_env : (env_storage = BuildEnvironmentArray(options.env_map));
options.full_env ? options.full_env
: (env_storage = BuildEnvironmentArray(options.env_map));
posix_spawn_file_actions_t file_actions;
int err = posix_spawn_file_actions_init(&file_actions);
@ -60,8 +62,8 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
DLOG(WARNING) << "posix_spawn_file_actions_init failed";
return Err(LaunchError("posix_spawn_file_actions_init", err));
}
auto file_actions_guard =
mozilla::MakeScopeExit([&file_actions] { posix_spawn_file_actions_destroy(&file_actions); });
auto file_actions_guard = mozilla::MakeScopeExit(
[&file_actions] { posix_spawn_file_actions_destroy(&file_actions); });
// Turn fds_to_remap array into a set of dup2 calls.
//
@ -85,7 +87,8 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
}
if (!options.workdir.empty()) {
int rv = posix_spawn_file_actions_addchdir_np(&file_actions, options.workdir.c_str());
int rv = posix_spawn_file_actions_addchdir_np(&file_actions,
options.workdir.c_str());
if (rv != 0) {
DLOG(WARNING) << "posix_spawn_file_actions_addchdir_np failed";
return Err(LaunchError("posix_spawn_file_actions_addchdir", rv));
@ -99,15 +102,16 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
DLOG(WARNING) << "posix_spawnattr_init failed";
return Err(LaunchError("posix_spawnattr_init", err));
}
auto spawnattr_guard =
mozilla::MakeScopeExit([&spawnattr] { posix_spawnattr_destroy(&spawnattr); });
auto spawnattr_guard = mozilla::MakeScopeExit(
[&spawnattr] { posix_spawnattr_destroy(&spawnattr); });
#if defined(XP_MACOSX) && defined(__aarch64__)
if (options.arch == PROCESS_ARCH_X86_64) {
cpu_type_t cpu_pref = CPU_TYPE_X86_64;
size_t count = 1;
size_t ocount = 0;
int rv = posix_spawnattr_setbinpref_np(&spawnattr, count, &cpu_pref, &ocount);
int rv =
posix_spawnattr_setbinpref_np(&spawnattr, count, &cpu_pref, &ocount);
if ((rv != 0) || (ocount != count)) {
DLOG(WARNING) << "posix_spawnattr_setbinpref_np failed";
return Err(LaunchError("posix_spawnattr_setbinpref_np", rv));
@ -142,15 +146,16 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
}
int pid = 0;
int spawn_succeeded =
(posix_spawnp(&pid, argv_copy[0], &file_actions, &spawnattr, argv_copy, vars.get()) == 0);
int spawn_succeeded = (posix_spawnp(&pid, argv_copy[0], &file_actions,
&spawnattr, argv_copy, vars.get()) == 0);
bool process_handle_valid = pid > 0;
if (!spawn_succeeded || !process_handle_valid) {
DLOG(WARNING) << "posix_spawnp failed";
retval = Err(LaunchError("posix_spawnp", spawn_succeeded));
} else {
gProcessLog.print("==> process %d launched child process %d\n", GetCurrentProcId(), pid);
gProcessLog.print("==> process %d launched child process %d\n",
GetCurrentProcId(), pid);
if (options.wait) HANDLE_EINTR(waitpid(pid, 0, 0));
if (process_handle) *process_handle = pid;
@ -159,7 +164,8 @@ Result<Ok, LaunchError> LaunchApp(const std::vector<std::string>& argv,
return retval;
}
Result<Ok, LaunchError> LaunchApp(const CommandLine& cl, const LaunchOptions& options,
Result<Ok, LaunchError> LaunchApp(const CommandLine& cl,
const LaunchOptions& options,
ProcessHandle* process_handle) {
return LaunchApp(cl.argv(), options, process_handle);
}

Просмотреть файл

@ -15,7 +15,9 @@ ScopedNSAutoreleasePool::ScopedNSAutoreleasePool()
DCHECK(autorelease_pool_);
}
ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() { [autorelease_pool_ drain]; }
ScopedNSAutoreleasePool::~ScopedNSAutoreleasePool() {
[autorelease_pool_ drain];
}
// Cycle the internal pool, allowing everything there to get cleaned up and
// start anew.

Просмотреть файл

@ -44,11 +44,12 @@ static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring,
out_size * sizeof(UInt8) / sizeof(typename StringType::value_type) + 1;
std::vector<typename StringType::value_type> out_buffer(elements);
converted = CFStringGetBytes(cfstring, whole_string, encoding,
0, // lossByte
false, // isExternalRepresentation
reinterpret_cast<UInt8*>(&out_buffer[0]), out_size,
NULL); // usedBufLen
converted =
CFStringGetBytes(cfstring, whole_string, encoding,
0, // lossByte
false, // isExternalRepresentation
reinterpret_cast<UInt8*>(&out_buffer[0]), out_size,
NULL); // usedBufLen
if (converted == 0) return StringType();
out_buffer[elements - 1] = '\0';
@ -61,31 +62,33 @@ static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring,
//
// Do not assert in this function since it is used by the asssertion code!
template <typename InStringType, typename OutStringType>
static OutStringType STLStringToSTLStringWithEncodingsT(const InStringType& in,
CFStringEncoding in_encoding,
CFStringEncoding out_encoding) {
static OutStringType STLStringToSTLStringWithEncodingsT(
const InStringType& in, CFStringEncoding in_encoding,
CFStringEncoding out_encoding) {
typename InStringType::size_type in_length = in.length();
if (in_length == 0) return OutStringType();
scoped_cftyperef<CFStringRef> cfstring(CFStringCreateWithBytesNoCopy(
NULL, reinterpret_cast<const UInt8*>(in.data()),
in_length * sizeof(typename InStringType::value_type), in_encoding, false, kCFAllocatorNull));
in_length * sizeof(typename InStringType::value_type), in_encoding, false,
kCFAllocatorNull));
if (!cfstring) return OutStringType();
return CFStringToSTLStringWithEncodingT<OutStringType>(cfstring, out_encoding);
return CFStringToSTLStringWithEncodingT<OutStringType>(cfstring,
out_encoding);
}
// Given an STL string |in| with an encoding specified by |in_encoding|,
// return it as a CFStringRef. Returns NULL on failure.
template <typename StringType>
static CFStringRef STLStringToCFStringWithEncodingsT(const StringType& in,
CFStringEncoding in_encoding) {
static CFStringRef STLStringToCFStringWithEncodingsT(
const StringType& in, CFStringEncoding in_encoding) {
typename StringType::size_type in_length = in.length();
if (in_length == 0) return CFSTR("");
return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(in.data()),
in_length * sizeof(typename StringType::value_type), in_encoding,
false);
return CFStringCreateWithBytes(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(in.data()),
in_length * sizeof(typename StringType::value_type), in_encoding, false);
}
// Specify the byte ordering explicitly, otherwise CFString will be confused
@ -102,18 +105,22 @@ static const CFStringEncoding kWideStringEncoding = kCFStringEncodingUTF32LE;
// Do not assert in this function since it is used by the asssertion code!
std::string SysWideToUTF8(const std::wstring& wide) {
return STLStringToSTLStringWithEncodingsT<std::wstring, std::string>(wide, kWideStringEncoding,
kNarrowStringEncoding);
return STLStringToSTLStringWithEncodingsT<std::wstring, std::string>(
wide, kWideStringEncoding, kNarrowStringEncoding);
}
// Do not assert in this function since it is used by the asssertion code!
std::wstring SysUTF8ToWide(const StringPiece& utf8) {
return STLStringToSTLStringWithEncodingsT<StringPiece, std::wstring>(utf8, kNarrowStringEncoding,
kWideStringEncoding);
return STLStringToSTLStringWithEncodingsT<StringPiece, std::wstring>(
utf8, kNarrowStringEncoding, kWideStringEncoding);
}
std::string SysWideToNativeMB(const std::wstring& wide) { return SysWideToUTF8(wide); }
std::string SysWideToNativeMB(const std::wstring& wide) {
return SysWideToUTF8(wide);
}
std::wstring SysNativeMBToWide(const StringPiece& native_mb) { return SysUTF8ToWide(native_mb); }
std::wstring SysNativeMBToWide(const StringPiece& native_mb) {
return SysUTF8ToWide(native_mb);
}
} // namespace base

Просмотреть файл

@ -20,7 +20,8 @@ NS_IMPL_ADDREF_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
NS_IMPL_RELEASE_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
NS_IMPL_QUERY_INTERFACE(MessagePumpForNonMainUIThreads, nsIThreadObserver)
MessagePumpForNonMainUIThreads::MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget)
MessagePumpForNonMainUIThreads::MessagePumpForNonMainUIThreads(
nsISerialEventTarget* aEventTarget)
: mEventTarget(aEventTarget), keep_running_(true) {
MOZ_ASSERT(mEventTarget);
CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
@ -36,13 +37,15 @@ MessagePumpForNonMainUIThreads::~MessagePumpForNonMainUIThreads() {
CFRelease(quit_source_);
}
void MessagePumpForNonMainUIThreads::DoRun(base::MessagePump::Delegate* aDelegate) {
// If this is a chromium thread and no nsThread is associated with it, this call will create a
// new nsThread.
void MessagePumpForNonMainUIThreads::DoRun(
base::MessagePump::Delegate* aDelegate) {
// If this is a chromium thread and no nsThread is associated with it, this
// call will create a new nsThread.
nsIThread* thread = NS_GetCurrentThread();
MOZ_ASSERT(thread);
// Set the main thread observer so we can wake up when xpcom events need to get processed.
// Set the main thread observer so we can wake up when xpcom events need to
// get processed.
nsCOMPtr<nsIThreadInternal> ti(do_QueryInterface(thread));
MOZ_ASSERT(ti);
ti->SetObserver(this);
@ -63,7 +66,8 @@ void MessagePumpForNonMainUIThreads::DoRun(base::MessagePump::Delegate* aDelegat
// Now process the CFRunLoop. It exits after running once.
// NSRunLoop manages autorelease pools itself.
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
}
ti->SetObserver(nullptr);
@ -77,14 +81,15 @@ void MessagePumpForNonMainUIThreads::Quit() {
}
NS_IMETHODIMP MessagePumpForNonMainUIThreads::OnDispatchedEvent() {
// ScheduleWork will signal an input source to the run loop, making it exit so it can process the
// xpcom event.
// ScheduleWork will signal an input source to the run loop, making it exit so
// it can process the xpcom event.
ScheduleWork();
return NS_OK;
}
NS_IMETHODIMP
MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal* thread, bool mayWait) {
MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal* thread,
bool mayWait) {
return NS_OK;
}

Просмотреть файл

@ -25,28 +25,32 @@ void SetThisProcessName(const char* aProcessName) {
return;
}
NSString* currentName =
[[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString* currentName = [[[NSBundle mainBundle] localizedInfoDictionary]
objectForKey:(NSString*)kCFBundleNameKey];
char formattedName[1024];
SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName);
SprintfLiteral(formattedName, "%s %s", [currentName UTF8String],
aProcessName);
aProcessName = formattedName;
// This function is based on Chrome/Webkit's and relies on potentially dangerous SPI.
// This function is based on Chrome/Webkit's and relies on potentially
// dangerous SPI.
typedef CFTypeRef (*LSGetASNType)();
typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef, CFStringRef,
CFDictionaryRef*);
typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef,
CFStringRef, CFDictionaryRef*);
CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
CFBundleRef launchServices =
::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
if (!launchServices) {
NS_WARNING("Failed to set process name: Could not open LaunchServices bundle");
NS_WARNING(
"Failed to set process name: Could not open LaunchServices bundle");
return;
}
if (!sApplicationASN) {
sApplicationASN =
::CFBundleGetFunctionPointerForName(launchServices, CFSTR("_LSGetCurrentApplicationASN"));
sApplicationASN = ::CFBundleGetFunctionPointerForName(
launchServices, CFSTR("_LSGetCurrentApplicationASN"));
if (!sApplicationASN) {
NS_WARNING("Failed to set process name: Could not get function pointer "
"for LaunchServices");
@ -64,12 +68,13 @@ void SetThisProcessName(const char* aProcessName) {
LSSetInformationItemType setInformationItemFunc =
reinterpret_cast<LSSetInformationItemType>(sApplicationInfoItem);
void* displayNameKeyAddr =
::CFBundleGetDataPointerForName(launchServices, CFSTR("_kLSDisplayNameKey"));
void* displayNameKeyAddr = ::CFBundleGetDataPointerForName(
launchServices, CFSTR("_kLSDisplayNameKey"));
CFStringRef displayNameKey = nil;
if (displayNameKeyAddr) {
displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
displayNameKey =
reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
}
// We need this to ensure we have a connection to the Process Manager, not
@ -81,20 +86,22 @@ void SetThisProcessName(const char* aProcessName) {
CFTypeRef currentAsn = getASNFunc ? getASNFunc() : nullptr;
if (!getASNFunc || !setInformationItemFunc || !displayNameKey || !currentAsn) {
if (!getASNFunc || !setInformationItemFunc || !displayNameKey ||
!currentAsn) {
NS_WARNING("Failed to set process name: Accessing launchServices failed");
return;
}
CFStringRef processName = ::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII);
CFStringRef processName =
::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII);
if (!processName) {
NS_WARNING("Failed to set process name: Could not create CFStringRef");
return;
}
OSErr err =
setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn, displayNameKey, processName,
nil); // Optional out param
OSErr err = setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn,
displayNameKey, processName,
nil); // Optional out param
::CFRelease(processName);
if (err != noErr) {
NS_WARNING("Failed to set process name: LSSetInformationItemType err");

Просмотреть файл

@ -71,12 +71,13 @@ bool SharedMemoryBasic::Create(size_t size) {
memory_object_size_t memoryObjectSize = round_page(size);
kern_return_t kr = mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, 0,
MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT,
getter_Transfers(mPort), MACH_PORT_NULL);
kern_return_t kr =
mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, 0,
MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT,
getter_Transfers(mPort), MACH_PORT_NULL);
if (kr != KERN_SUCCESS || memoryObjectSize < round_page(size)) {
LOG_ERROR("Failed to make memory entry (%zu bytes). %s (%x)\n", size, mach_error_string(kr),
kr);
LOG_ERROR("Failed to make memory entry (%zu bytes). %s (%x)\n", size,
mach_error_string(kr), kr);
CloseHandle();
return false;
}
@ -101,12 +102,15 @@ bool SharedMemoryBasic::Map(size_t size, void* fixed_address) {
}
kr = mach_vm_map(mach_task_self(), &address, round_page(size), 0,
fixed_address ? VM_FLAGS_FIXED : VM_FLAGS_ANYWHERE, mPort.get(), 0, false,
vmProtection, vmProtection, VM_INHERIT_NONE);
fixed_address ? VM_FLAGS_FIXED : VM_FLAGS_ANYWHERE,
mPort.get(), 0, false, vmProtection, vmProtection,
VM_INHERIT_NONE);
if (kr != KERN_SUCCESS) {
if (!fixed_address) {
LOG_ERROR("Failed to map shared memory (%zu bytes) into %x, port %x. %s (%x)\n", size,
mach_task_self(), mach_port_t(mPort.get()), mach_error_string(kr), kr);
LOG_ERROR(
"Failed to map shared memory (%zu bytes) into %x, port %x. %s (%x)\n",
size, mach_task_self(), mach_port_t(mPort.get()),
mach_error_string(kr), kr);
}
return false;
}
@ -116,7 +120,8 @@ bool SharedMemoryBasic::Map(size_t size, void* fixed_address) {
if (kr != KERN_SUCCESS) {
LOG_ERROR("Failed to unmap shared memory at unsuitable address "
"(%zu bytes) from %x, port %x. %s (%x)\n",
size, mach_task_self(), mach_port_t(mPort.get()), mach_error_string(kr), kr);
size, mach_task_self(), mach_port_t(mPort.get()),
mach_error_string(kr), kr);
}
return false;
}
@ -129,8 +134,9 @@ bool SharedMemoryBasic::Map(size_t size, void* fixed_address) {
void* SharedMemoryBasic::FindFreeAddressSpace(size_t size) {
mach_vm_address_t address = 0;
size = round_page(size);
if (mach_vm_map(mach_task_self(), &address, size, 0, VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, 0,
false, VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_NONE) != KERN_SUCCESS ||
if (mach_vm_map(mach_task_self(), &address, size, 0, VM_FLAGS_ANYWHERE,
MEMORY_OBJECT_NULL, 0, false, VM_PROT_NONE, VM_PROT_NONE,
VM_INHERIT_NONE) != KERN_SUCCESS ||
vm_deallocate(mach_task_self(), address, size) != KERN_SUCCESS) {
return nullptr;
}
@ -146,9 +152,11 @@ void SharedMemoryBasic::Unmap() {
return;
}
vm_address_t address = toVMAddress(mMemory);
kern_return_t kr = vm_deallocate(mach_task_self(), address, round_page(mMappedSize));
kern_return_t kr =
vm_deallocate(mach_task_self(), address, round_page(mMappedSize));
if (kr != KERN_SUCCESS) {
LOG_ERROR("Failed to deallocate shared memory. %s (%x)\n", mach_error_string(kr), kr);
LOG_ERROR("Failed to deallocate shared memory. %s (%x)\n",
mach_error_string(kr), kr);
return;
}
mMemory = nullptr;
@ -161,7 +169,9 @@ void SharedMemoryBasic::CloseHandle() {
}
}
bool SharedMemoryBasic::IsHandleValid(const Handle& aHandle) const { return aHandle != nullptr; }
bool SharedMemoryBasic::IsHandleValid(const Handle& aHandle) const {
return aHandle != nullptr;
}
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -75,7 +75,9 @@ static OSStatus getErrorCodeBool(Boolean success) {
}
// If given a NULL pointer, return the error code.
static OSStatus getErrorCodePtr(const void* value) { return getErrorCodeBool(value != nullptr); }
static OSStatus getErrorCodePtr(const void* value) {
return getErrorCodeBool(value != nullptr);
}
// Convenience function to allow NULL input.
static void CFReleaseSafe(CFTypeRef cf) {
@ -86,8 +88,8 @@ static void CFReleaseSafe(CFTypeRef cf) {
}
}
NS_IMPL_ISUPPORTS(nsNetworkLinkService, nsINetworkLinkService, nsIObserver, nsITimerCallback,
nsINamed)
NS_IMPL_ISUPPORTS(nsNetworkLinkService, nsINetworkLinkService, nsIObserver,
nsITimerCallback, nsINamed)
nsNetworkLinkService::nsNetworkLinkService()
: mLinkUp(true),
@ -129,7 +131,8 @@ nsNetworkLinkService::GetNetworkID(nsACString& aNetworkID) {
}
NS_IMETHODIMP
nsNetworkLinkService::GetPlatformDNSIndications(uint32_t* aPlatformDNSIndications) {
nsNetworkLinkService::GetPlatformDNSIndications(
uint32_t* aPlatformDNSIndications) {
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -139,8 +142,9 @@ void nsNetworkLinkService::GetDnsSuffixListInternal() {
auto sendNotification = mozilla::MakeScopeExit([self = RefPtr{this}] {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"nsNetworkLinkService::GetDnsSuffixListInternal",
[self]() { self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr); }));
"nsNetworkLinkService::GetDnsSuffixListInternal", [self]() {
self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr);
}));
});
nsTArray<nsCString> result;
@ -176,15 +180,17 @@ nsNetworkLinkService::GetResolvers(nsTArray<RefPtr<nsINetAddr>>& aResolvers) {
}
NS_IMETHODIMP
nsNetworkLinkService::GetNativeResolvers(nsTArray<mozilla::net::NetAddr>& aResolvers) {
nsNetworkLinkService::GetNativeResolvers(
nsTArray<mozilla::net::NetAddr>& aResolvers) {
return NS_ERROR_NOT_IMPLEMENTED;
}
#ifndef SA_SIZE
# define SA_SIZE(sa) \
((!(sa) || ((struct sockaddr*)(sa))->sa_len == 0) \
? sizeof(uint32_t) \
: 1 + ((((struct sockaddr*)(sa))->sa_len - 1) | (sizeof(uint32_t) - 1)))
# define SA_SIZE(sa) \
((!(sa) || ((struct sockaddr*)(sa))->sa_len == 0) \
? sizeof(uint32_t) \
: 1 + ((((struct sockaddr*)(sa))->sa_len - 1) | \
(sizeof(uint32_t) - 1)))
#endif
static bool getMac(struct sockaddr_dl* sdl, char* buf, size_t bufsize) {
@ -196,14 +202,14 @@ static bool getMac(struct sockaddr_dl* sdl, char* buf, size_t bufsize) {
return false;
}
snprintf(buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4],
mac[5]);
snprintf(buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1],
mac[2], mac[3], mac[4], mac[5]);
return true;
}
/* If the IP matches, get the MAC and return true */
static bool matchIp(struct sockaddr_dl* sdl, struct sockaddr_inarp* addr, char* ip, char* buf,
size_t bufsize) {
static bool matchIp(struct sockaddr_dl* sdl, struct sockaddr_inarp* addr,
char* ip, char* buf, size_t bufsize) {
if (sdl->sdl_alen) {
if (!strcmp(inet_ntoa(addr->sin_addr), ip)) {
if (getMac(sdl, buf, bufsize)) {
@ -275,8 +281,10 @@ static bool scanArp(char* ip, char* mac, size_t maclen) {
struct rt_msghdr* rtm;
for (next = &buf[0]; next < lim; next += rtm->rtm_msglen) {
rtm = reinterpret_cast<struct rt_msghdr*>(next);
struct sockaddr_inarp* sin2 = reinterpret_cast<struct sockaddr_inarp*>(rtm + 1);
struct sockaddr_dl* sdl = reinterpret_cast<struct sockaddr_dl*>((char*)sin2 + SA_SIZE(sin2));
struct sockaddr_inarp* sin2 =
reinterpret_cast<struct sockaddr_inarp*>(rtm + 1);
struct sockaddr_dl* sdl =
reinterpret_cast<struct sockaddr_dl*>((char*)sin2 + SA_SIZE(sin2));
if (matchIp(sdl, sin2, ip, mac, maclen)) {
return true;
}
@ -285,9 +293,10 @@ static bool scanArp(char* ip, char* mac, size_t maclen) {
return false;
}
// Append the mac address of rtm to `stringsToHash`. If it's not in arp table, append
// ifname and IP address.
static bool parseHashKey(struct rt_msghdr* rtm, nsTArray<nsCString>& stringsToHash,
// Append the mac address of rtm to `stringsToHash`. If it's not in arp table,
// append ifname and IP address.
static bool parseHashKey(struct rt_msghdr* rtm,
nsTArray<nsCString>& stringsToHash,
bool skipDstCheck) {
struct sockaddr* sa;
struct sockaddr_in* sockin;
@ -317,8 +326,8 @@ static bool parseHashKey(struct rt_msghdr* rtm, nsTArray<nsCString>& stringsToHa
return false;
}
struct sockaddr* gateway =
reinterpret_cast<struct sockaddr*>((char*)sa + RTAX_GATEWAY * SA_SIZE(sa));
struct sockaddr* gateway = reinterpret_cast<struct sockaddr*>(
(char*)sa + RTAX_GATEWAY * SA_SIZE(sa));
if (!gateway) {
return false;
@ -440,7 +449,8 @@ bool nsNetworkLinkService::RoutingFromKernel(nsTArray<nsCString>& aHash) {
sin->sin_addr = mRouteCheckIPv4;
if (write(sockfd, rtm, rtm->rtm_msglen) == -1) {
LOG(("RoutingFromKernel: write() failed. No route to the predefine destincation"));
LOG(("RoutingFromKernel: write() failed. No route to the predefine "
"destincation"));
return false;
}
@ -451,9 +461,11 @@ bool nsNetworkLinkService::RoutingFromKernel(nsTArray<nsCString>& aHash) {
return false;
}
LOG(("RoutingFromKernel: read() rtm_type: %d (%d), rtm_pid: %d (%d), rtm_seq: %d (%d)\n",
LOG(("RoutingFromKernel: read() rtm_type: %d (%d), rtm_pid: %d (%d), "
"rtm_seq: %d (%d)\n",
rtm->rtm_type, RTM_GET, rtm->rtm_pid, pid, rtm->rtm_seq, seq));
} while (rtm->rtm_type != RTM_GET || rtm->rtm_pid != pid || rtm->rtm_seq != seq);
} while (rtm->rtm_type != RTM_GET || rtm->rtm_pid != pid ||
rtm->rtm_seq != seq);
return parseHashKey(rtm, aHash, true);
}
@ -489,8 +501,9 @@ bool nsNetworkLinkService::IPv4NetworkId(SHA1Sum* aSHA1) {
//
void nsNetworkLinkService::HashSortedPrefixesAndNetmasks(
std::vector<prefix_and_netmask> prefixAndNetmaskStore, SHA1Sum* sha1) {
// getifaddrs does not guarantee the interfaces will always be in the same order.
// We want to make sure the hash remains consistent Regardless of the interface order.
// getifaddrs does not guarantee the interfaces will always be in the same
// order. We want to make sure the hash remains consistent Regardless of the
// interface order.
std::sort(prefixAndNetmaskStore.begin(), prefixAndNetmaskStore.end(),
[](prefix_and_netmask a, prefix_and_netmask b) {
// compare prefixStore
@ -521,7 +534,8 @@ bool nsNetworkLinkService::IPv6NetworkId(SHA1Sum* sha1) {
if ((AF_INET6 == ifa->ifa_addr->sa_family) &&
!(ifa->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))) {
// only IPv6 interfaces that aren't pointtopoint or loopback
struct sockaddr_in6* sin_netmask = (struct sockaddr_in6*)ifa->ifa_netmask;
struct sockaddr_in6* sin_netmask =
(struct sockaddr_in6*)ifa->ifa_netmask;
if (sin_netmask) {
struct sockaddr_in6* sin_addr = (struct sockaddr_in6*)ifa->ifa_addr;
int scope = net::utils::ipv6_scope(sin_addr->sin6_addr.s6_addr);
@ -530,17 +544,20 @@ bool nsNetworkLinkService::IPv6NetworkId(SHA1Sum* sha1) {
memset(&prefix, 0, sizeof(prefix));
// Get the prefix by combining the address and netmask.
for (size_t i = 0; i < sizeof(prefix); ++i) {
prefix.s6_addr[i] =
sin_addr->sin6_addr.s6_addr[i] & sin_netmask->sin6_addr.s6_addr[i];
prefix.s6_addr[i] = sin_addr->sin6_addr.s6_addr[i] &
sin_netmask->sin6_addr.s6_addr[i];
}
// check if prefix and netmask was already found
auto prefixAndNetmask = std::make_pair(prefix, sin_netmask->sin6_addr);
auto prefixAndNetmask =
std::make_pair(prefix, sin_netmask->sin6_addr);
auto foundPosition = std::find_if(
prefixAndNetmaskStore.begin(), prefixAndNetmaskStore.end(),
[&prefixAndNetmask](prefix_and_netmask current) {
return memcmp(&prefixAndNetmask.first, &current.first, sizeof(in6_addr)) == 0 &&
memcmp(&prefixAndNetmask.second, &current.second, sizeof(in6_addr)) == 0;
return memcmp(&prefixAndNetmask.first, &current.first,
sizeof(in6_addr)) == 0 &&
memcmp(&prefixAndNetmask.second, &current.second,
sizeof(in6_addr)) == 0;
});
if (foundPosition != prefixAndNetmaskStore.end()) {
continue;
@ -557,7 +574,8 @@ bool nsNetworkLinkService::IPv6NetworkId(SHA1Sum* sha1) {
return false;
}
nsNetworkLinkService::HashSortedPrefixesAndNetmasks(prefixAndNetmaskStore, sha1);
nsNetworkLinkService::HashSortedPrefixesAndNetmasks(prefixAndNetmaskStore,
sha1);
return true;
}
@ -577,15 +595,17 @@ void nsNetworkLinkService::calculateNetworkIdWithDelay(uint32_t aDelay) {
return;
}
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
nsCOMPtr<nsIEventTarget> target =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
if (!target) {
return;
}
MOZ_ALWAYS_SUCCEEDS(
target->Dispatch(NewRunnableMethod("nsNetworkLinkService::calculateNetworkIdInternal", this,
&nsNetworkLinkService::calculateNetworkIdInternal),
NS_DISPATCH_NORMAL));
MOZ_ALWAYS_SUCCEEDS(target->Dispatch(
NewRunnableMethod("nsNetworkLinkService::calculateNetworkIdInternal",
this,
&nsNetworkLinkService::calculateNetworkIdInternal),
NS_DISPATCH_NORMAL));
}
NS_IMETHODIMP
@ -615,7 +635,8 @@ void nsNetworkLinkService::calculateNetworkIdInternal(void) {
SeedNetworkId(sha1);
uint8_t digest[SHA1Sum::kHashSize];
sha1.finish(digest);
nsAutoCString newString(reinterpret_cast<char*>(digest), SHA1Sum::kHashSize);
nsAutoCString newString(reinterpret_cast<char*>(digest),
SHA1Sum::kHashSize);
nsresult rv = Base64Encode(newString, output);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
LOG(("networkid: id %s\n", output.get()));
@ -652,16 +673,17 @@ void nsNetworkLinkService::calculateNetworkIdInternal(void) {
if (idChanged && !initialIDCalculation) {
RefPtr<nsNetworkLinkService> self = this;
NS_DispatchToMainThread(
NS_NewRunnableFunction("nsNetworkLinkService::calculateNetworkIdInternal",
[self]() { self->OnNetworkIdChanged(); }));
NS_DispatchToMainThread(NS_NewRunnableFunction(
"nsNetworkLinkService::calculateNetworkIdInternal",
[self]() { self->OnNetworkIdChanged(); }));
}
initialIDCalculation = false;
}
NS_IMETHODIMP
nsNetworkLinkService::Observe(nsISupports* subject, const char* topic, const char16_t* data) {
nsNetworkLinkService::Observe(nsISupports* subject, const char* topic,
const char16_t* data) {
if (!strcmp(topic, "xpcom-shutdown")) {
Shutdown();
}
@ -671,14 +693,17 @@ nsNetworkLinkService::Observe(nsISupports* subject, const char* topic, const cha
/* static */
void nsNetworkLinkService::NetworkConfigChanged(SCDynamicStoreRef aStoreREf,
CFArrayRef aChangedKeys, void* aInfo) {
CFArrayRef aChangedKeys,
void* aInfo) {
LOG(("nsNetworkLinkService::NetworkConfigChanged"));
bool ipConfigChanged = false;
bool dnsConfigChanged = false;
for (CFIndex i = 0; i < CFArrayGetCount(aChangedKeys); ++i) {
CFStringRef key = static_cast<CFStringRef>(CFArrayGetValueAtIndex(aChangedKeys, i));
if (CFStringHasSuffix(key, kSCEntNetIPv4) || CFStringHasSuffix(key, kSCEntNetIPv6)) {
CFStringRef key =
static_cast<CFStringRef>(CFArrayGetValueAtIndex(aChangedKeys, i));
if (CFStringHasSuffix(key, kSCEntNetIPv4) ||
CFStringHasSuffix(key, kSCEntNetIPv6)) {
ipConfigChanged = true;
}
if (CFStringHasSuffix(key, kSCEntNetDNS)) {
@ -698,7 +723,8 @@ void nsNetworkLinkService::NetworkConfigChanged(SCDynamicStoreRef aStoreREf,
void nsNetworkLinkService::DNSConfigChanged(uint32_t aDelayMs) {
LOG(("nsNetworkLinkService::DNSConfigChanged"));
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
nsCOMPtr<nsIEventTarget> target =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
if (!target) {
return;
}
@ -717,9 +743,9 @@ void nsNetworkLinkService::DNSConfigChanged(uint32_t aDelayMs) {
"nsNetworkLinkService::GetDnsSuffixListInternal", target));
mDNSConfigChangedTimers.AppendElement(timer);
} else {
MOZ_ALWAYS_SUCCEEDS(target->Dispatch(
NS_NewRunnableFunction("nsNetworkLinkService::GetDnsSuffixListInternal",
[self = RefPtr{this}]() { self->GetDnsSuffixListInternal(); })));
MOZ_ALWAYS_SUCCEEDS(target->Dispatch(NS_NewRunnableFunction(
"nsNetworkLinkService::GetDnsSuffixListInternal",
[self = RefPtr{this}]() { self->GetDnsSuffixListInternal(); })));
}
}
@ -745,13 +771,15 @@ nsresult nsNetworkLinkService::Init(void) {
bzero(&addr, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
mReachability = ::SCNetworkReachabilityCreateWithAddress(nullptr, (struct sockaddr*)&addr);
mReachability = ::SCNetworkReachabilityCreateWithAddress(
nullptr, (struct sockaddr*)&addr);
if (!mReachability) {
return NS_ERROR_NOT_AVAILABLE;
}
SCNetworkReachabilityContext context = {0, this, nullptr, nullptr, nullptr};
if (!::SCNetworkReachabilitySetCallback(mReachability, ReachabilityChanged, &context)) {
if (!::SCNetworkReachabilitySetCallback(mReachability, ReachabilityChanged,
&context)) {
NS_WARNING("SCNetworkReachabilitySetCallback failed.");
::CFRelease(mReachability);
mReachability = nullptr;
@ -759,24 +787,25 @@ nsresult nsNetworkLinkService::Init(void) {
}
SCDynamicStoreContext storeContext = {0, this, nullptr, nullptr, nullptr};
mStoreRef = ::SCDynamicStoreCreate(nullptr, CFSTR("IPAndDNSChangeCallbackSCF"),
NetworkConfigChanged, &storeContext);
mStoreRef =
::SCDynamicStoreCreate(nullptr, CFSTR("IPAndDNSChangeCallbackSCF"),
NetworkConfigChanged, &storeContext);
CFStringRef patterns[4] = {nullptr, nullptr, nullptr, nullptr};
OSStatus err = getErrorCodePtr(mStoreRef);
if (err == noErr) {
// This pattern is "State:/Network/Service/[^/]+/IPv4".
patterns[0] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(nullptr, kSCDynamicStoreDomainState,
kSCCompAnyRegex, kSCEntNetIPv4);
patterns[0] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(
nullptr, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4);
// This pattern is "State:/Network/Service/[^/]+/IPv6".
patterns[1] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(nullptr, kSCDynamicStoreDomainState,
kSCCompAnyRegex, kSCEntNetIPv6);
patterns[1] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(
nullptr, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6);
// This pattern is "State:/Network/Service/[^/]+/DNS".
patterns[2] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(nullptr, kSCDynamicStoreDomainState,
kSCCompAnyRegex, kSCEntNetDNS);
patterns[2] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(
nullptr, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetDNS);
// This pattern is "Setup:/Network/Service/[^/]+/DNS".
patterns[3] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(nullptr, kSCDynamicStoreDomainSetup,
kSCCompAnyRegex, kSCEntNetDNS);
patterns[3] = ::SCDynamicStoreKeyCreateNetworkServiceEntity(
nullptr, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetDNS);
if (!patterns[0] || !patterns[1] || !patterns[2] || !patterns[3]) {
err = -1;
}
@ -788,13 +817,15 @@ nsresult nsNetworkLinkService::Init(void) {
// that match that pattern list, then create our run loop
// source.
if (err == noErr) {
patternList = ::CFArrayCreate(nullptr, (const void**)patterns, 4, &kCFTypeArrayCallBacks);
patternList = ::CFArrayCreate(nullptr, (const void**)patterns, 4,
&kCFTypeArrayCallBacks);
if (!patternList) {
err = -1;
}
}
if (err == noErr) {
err = getErrorCodeBool(::SCDynamicStoreSetNotificationKeys(mStoreRef, nullptr, patternList));
err = getErrorCodeBool(
::SCDynamicStoreSetNotificationKeys(mStoreRef, nullptr, patternList));
}
if (err == noErr) {
@ -925,26 +956,31 @@ void nsNetworkLinkService::OnReachabilityChanged() {
return;
}
NotifyObservers(NS_NETWORK_LINK_TOPIC,
mLinkUp ? NS_NETWORK_LINK_DATA_UP : NS_NETWORK_LINK_DATA_DOWN);
NotifyObservers(NS_NETWORK_LINK_TOPIC, mLinkUp ? NS_NETWORK_LINK_DATA_UP
: NS_NETWORK_LINK_DATA_DOWN);
}
void nsNetworkLinkService::NotifyObservers(const char* aTopic, const char* aData) {
void nsNetworkLinkService::NotifyObservers(const char* aTopic,
const char* aData) {
MOZ_ASSERT(NS_IsMainThread());
LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic, aData ? aData : ""));
LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic,
aData ? aData : ""));
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->NotifyObservers(static_cast<nsINetworkLinkService*>(this), aTopic,
aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr);
observerService->NotifyObservers(
static_cast<nsINetworkLinkService*>(this), aTopic,
aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr);
}
}
/* static */
void nsNetworkLinkService::ReachabilityChanged(SCNetworkReachabilityRef target,
SCNetworkConnectionFlags flags, void* info) {
SCNetworkConnectionFlags flags,
void* info) {
LOG(("nsNetworkLinkService::ReachabilityChanged"));
nsNetworkLinkService* service = static_cast<nsNetworkLinkService*>(info);

Просмотреть файл

@ -29,7 +29,8 @@ nsresult WifiScannerImpl::GetAccessPointsFromWLAN(
@try {
NSBundle* bundle = [[[NSBundle alloc]
initWithPath:@"/System/Library/Frameworks/CoreWLAN.framework"] autorelease];
initWithPath:@"/System/Library/Frameworks/CoreWLAN.framework"]
autorelease];
if (!bundle) {
[pool release];
return NS_ERROR_NOT_AVAILABLE;
@ -41,7 +42,8 @@ nsresult WifiScannerImpl::GetAccessPointsFromWLAN(
return NS_ERROR_NOT_AVAILABLE;
}
id scanResult = [[CWI_class interface] scanForNetworksWithSSID:nil error:nil];
id scanResult = [[CWI_class interface] scanForNetworksWithSSID:nil
error:nil];
if (!scanResult) {
[pool release];
return NS_ERROR_NOT_AVAILABLE;
@ -73,7 +75,8 @@ nsresult WifiScannerImpl::GetAccessPointsFromWLAN(
NSString* macString = [anObject bssid];
if (macString && ([macString length] == 17)) {
for (NSUInteger i = 0; i < 6; ++i) {
NSString* part = [macString substringWithRange:NSMakeRange(i * 3, 2)];
NSString* part =
[macString substringWithRange:NSMakeRange(i * 3, 2)];
NSScanner* scanner = [NSScanner scannerWithString:part];
unsigned int data = 0;
if (![scanner scanHexInt:&data]) {

Просмотреть файл

@ -35,12 +35,15 @@ nsresult ReauthenticateUserMacOS(const nsAString& aPrompt,
localizedReason:prompt
reply:^(BOOL success, NSError* error) {
dispatch_async(dispatch_get_main_queue(), ^{
// error is not particularly useful in this context, and we have no
// mechanism to really return it. We could use it to set the nsresult,
// but this is a best-effort mechanism and there's no particular case for
// propagating up XPCOM. The one exception being a user account that
// has no passcode set, which we handle below.
errorPasswordNotSet = error && [error code] == kPasswordNotSetErrorCode;
// error is not particularly useful in this context, and
// we have no mechanism to really return it. We could
// use it to set the nsresult, but this is a best-effort
// mechanism and there's no particular case for
// propagating up XPCOM. The one exception being a user
// account that has no passcode set, which we handle
// below.
errorPasswordNotSet =
error && [error code] == kPasswordNotSetErrorCode;
biometricSuccess = success || errorPasswordNotSet;
dispatch_semaphore_signal(sema);
});

Просмотреть файл

@ -33,7 +33,8 @@
// Undocumented sandbox setup routines.
extern "C" int sandbox_init_with_parameters(const char* profile, uint64_t flags,
const char* const parameters[], char** errorbuf);
const char* const parameters[],
char** errorbuf);
extern "C" void sandbox_free_error(char* errorbuf);
extern "C" int sandbox_check(pid_t pid, const char* operation, int type, ...);
@ -50,7 +51,8 @@ class OSXVersion {
static void Get(int32_t& aMajor, int32_t& aMinor);
private:
static void GetSystemVersion(int32_t& aMajor, int32_t& aMinor, int32_t& aBugFix);
static void GetSystemVersion(int32_t& aMajor, int32_t& aMinor,
int32_t& aBugFix);
static bool mCached;
static int32_t mOSXVersionMajor;
static int32_t mOSXVersionMinor;
@ -72,23 +74,26 @@ void OSXVersion::Get(int32_t& aMajor, int32_t& aMinor) {
aMinor = mOSXVersionMinor;
}
void OSXVersion::GetSystemVersion(int32_t& aMajor, int32_t& aMinor, int32_t& aBugFix) {
void OSXVersion::GetSystemVersion(int32_t& aMajor, int32_t& aMinor,
int32_t& aBugFix) {
SInt32 major = 0, minor = 0, bugfix = 0;
CFURLRef url = CFURLCreateWithString(
kCFAllocatorDefault, CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"), NULL);
kCFAllocatorDefault,
CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"), NULL);
CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
CFReadStreamOpen(stream);
CFDictionaryRef sysVersionPlist = (CFDictionaryRef)CFPropertyListCreateWithStream(
kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL);
CFDictionaryRef sysVersionPlist =
(CFDictionaryRef)CFPropertyListCreateWithStream(
kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL);
CFReadStreamClose(stream);
CFRelease(stream);
CFRelease(url);
CFStringRef versionString =
(CFStringRef)CFDictionaryGetValue(sysVersionPlist, CFSTR("ProductVersion"));
CFArrayRef versions =
CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault, versionString, CFSTR("."));
CFStringRef versionString = (CFStringRef)CFDictionaryGetValue(
sysVersionPlist, CFSTR("ProductVersion"));
CFArrayRef versions = CFStringCreateArrayBySeparatingStrings(
kCFAllocatorDefault, versionString, CFSTR("."));
CFIndex count = CFArrayGetCount(versions);
if (count > 0) {
CFStringRef component = (CFStringRef)CFArrayGetValueAtIndex(versions, 0);
@ -188,22 +193,26 @@ void MacSandboxInfo::AppendAsParams(std::vector<std::string>& aParams) const {
}
}
void MacSandboxInfo::AppendStartupParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendStartupParam(
std::vector<std::string>& aParams) const {
aParams.push_back("-sbStartup");
}
void MacSandboxInfo::AppendLoggingParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendLoggingParam(
std::vector<std::string>& aParams) const {
if (this->shouldLog) {
aParams.push_back("-sbLogging");
}
}
void MacSandboxInfo::AppendAppPathParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendAppPathParam(
std::vector<std::string>& aParams) const {
aParams.push_back("-sbAppPath");
aParams.push_back(this->appPath);
}
void MacSandboxInfo::AppendPluginPathParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendPluginPathParam(
std::vector<std::string>& aParams) const {
aParams.push_back("-sbPluginPath");
aParams.push_back(this->pluginPath);
}
@ -230,13 +239,15 @@ void MacSandboxInfo::AppendAudioParam(std::vector<std::string>& aParams) const {
}
}
void MacSandboxInfo::AppendWindowServerParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendWindowServerParam(
std::vector<std::string>& aParams) const {
if (this->hasWindowServer) {
aParams.push_back("-sbAllowWindowServer");
}
}
void MacSandboxInfo::AppendReadPathParams(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendReadPathParams(
std::vector<std::string>& aParams) const {
if (!this->testingReadPath1.empty()) {
aParams.push_back("-sbTestingReadPath");
aParams.push_back(this->testingReadPath1.c_str());
@ -256,7 +267,8 @@ void MacSandboxInfo::AppendReadPathParams(std::vector<std::string>& aParams) con
}
#ifdef DEBUG
void MacSandboxInfo::AppendDebugWriteDirParam(std::vector<std::string>& aParams) const {
void MacSandboxInfo::AppendDebugWriteDirParam(
std::vector<std::string>& aParams) const {
if (!this->debugWriteDir.empty()) {
aParams.push_back("-sbDebugWriteDir");
aParams.push_back(this->debugWriteDir.c_str());
@ -430,7 +442,8 @@ bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
profile.append(SandboxPolicyContentAudioAddend);
}
} else {
fprintf(stderr, "Content sandbox disabled due to sandbox level setting\n");
fprintf(stderr,
"Content sandbox disabled due to sandbox level setting\n");
return false;
}
} else {
@ -465,7 +478,8 @@ bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
params.push_back(nullptr);
char* errorbuf = NULL;
int rv = sandbox_init_with_parameters(profile.c_str(), 0, params.data(), &errorbuf);
int rv = sandbox_init_with_parameters(profile.c_str(), 0, params.data(),
&errorbuf);
if (rv) {
if (errorbuf) {
char* msg = NULL;
@ -490,7 +504,8 @@ bool StartMacSandbox(MacSandboxInfo const& aInfo, std::string& aErrorMessage) {
* command line arguments. Return false if any sandbox parameters needed
* for early startup of the sandbox are not present in the arguments.
*/
bool GetContentSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
bool GetContentSandboxParamsFromArgs(int aArgc, char** aArgv,
MacSandboxInfo& aInfo) {
// Ensure we find these paramaters in the command
// line arguments. Return false if any are missing.
bool foundSandboxLevel = false;
@ -604,7 +619,8 @@ bool GetContentSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aI
return true;
}
bool GetUtilitySandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo,
bool GetUtilitySandboxParamsFromArgs(int aArgc, char** aArgv,
MacSandboxInfo& aInfo,
bool aSandboxingKindRequired = true) {
// Ensure we find these paramaters in the command
// line arguments. Return false if any are missing.
@ -650,11 +666,13 @@ bool GetUtilitySandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aI
return true;
}
bool GetSocketSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
bool GetSocketSandboxParamsFromArgs(int aArgc, char** aArgv,
MacSandboxInfo& aInfo) {
return GetUtilitySandboxParamsFromArgs(aArgc, aArgv, aInfo, false);
}
bool GetPluginSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
bool GetPluginSandboxParamsFromArgs(int aArgc, char** aArgv,
MacSandboxInfo& aInfo) {
// Ensure we find these paramaters in the command
// line arguments. Return false if any are missing.
bool foundAppPath = false;
@ -725,7 +743,8 @@ bool GetPluginSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aIn
return true;
}
bool GetRDDSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo) {
bool GetRDDSandboxParamsFromArgs(int aArgc, char** aArgv,
MacSandboxInfo& aInfo) {
return GetUtilitySandboxParamsFromArgs(aArgc, aArgv, aInfo, false);
}
@ -733,8 +752,8 @@ bool GetRDDSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo)
* Returns true if no errors were encountered or if early sandbox startup is
* not enabled for this process. Returns false if an error was encountered.
*/
bool StartMacSandboxIfEnabled(const MacSandboxType aSandboxType, int aArgc, char** aArgv,
std::string& aErrorMessage) {
bool StartMacSandboxIfEnabled(const MacSandboxType aSandboxType, int aArgc,
char** aArgv, std::string& aErrorMessage) {
bool earlyStartupEnabled = false;
// Check for the -sbStartup CLI parameter which
@ -796,7 +815,9 @@ bool IsMacSandboxStarted() { return sandbox_check(getpid(), NULL, 0) == 1; }
#ifdef DEBUG
// sandbox_check returns 1 if the specified process is sandboxed
void AssertMacSandboxEnabled() { MOZ_ASSERT(sandbox_check(getpid(), NULL, 0) == 1); }
void AssertMacSandboxEnabled() {
MOZ_ASSERT(sandbox_check(getpid(), NULL, 0) == 1);
}
#endif /* DEBUG */
} // namespace mozilla

Просмотреть файл

@ -12,8 +12,8 @@
NS_IMPL_ISUPPORTS(nsParentalControlsService, nsIParentalControlsService)
nsParentalControlsService::nsParentalControlsService() : mEnabled(false) {
mEnabled = CFPreferencesAppValueIsForced(CFSTR("restrictWeb"),
CFSTR("com.apple.familycontrols.contentfilter"));
mEnabled = CFPreferencesAppValueIsForced(
CFSTR("restrictWeb"), CFSTR("com.apple.familycontrols.contentfilter"));
}
nsParentalControlsService::~nsParentalControlsService() {}
@ -37,13 +37,14 @@ nsParentalControlsService::GetLoggingEnabled(bool* aResult) {
}
NS_IMETHODIMP
nsParentalControlsService::Log(int16_t aEntryType, bool blocked, nsIURI* aSource,
nsIFile* aTarget) {
nsParentalControlsService::Log(int16_t aEntryType, bool blocked,
nsIURI* aSource, nsIFile* aTarget) {
// silently drop on the floor
return NS_OK;
}
NS_IMETHODIMP
nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri, bool* _retval) {
nsParentalControlsService::IsAllowed(int16_t aAction, nsIURI* aUri,
bool* _retval) {
return NS_ERROR_NOT_AVAILABLE;
}

Просмотреть файл

@ -31,7 +31,8 @@ namespace mozilla {
nsresult GetCpuTimeSinceProcessStartInMs(uint64_t* aResult) {
struct proc_taskinfo pti;
if ((unsigned long)proc_pidinfo(getpid(), PROC_PIDTASKINFO, 0, &pti, PROC_PIDTASKINFO_SIZE) <
if ((unsigned long)proc_pidinfo(getpid(), PROC_PIDTASKINFO, 0, &pti,
PROC_PIDTASKINFO_SIZE) <
PROC_PIDTASKINFO_SIZE) {
return NS_ERROR_FAILURE;
}
@ -39,16 +40,16 @@ nsresult GetCpuTimeSinceProcessStartInMs(uint64_t* aResult) {
mach_timebase_info_data_t timebase;
GetTimeBase(&timebase);
*aResult = (pti.pti_total_user + pti.pti_total_system) * timebase.numer / timebase.denom /
PR_NSEC_PER_MSEC;
*aResult = (pti.pti_total_user + pti.pti_total_system) * timebase.numer /
timebase.denom / PR_NSEC_PER_MSEC;
return NS_OK;
}
nsresult GetGpuTimeSinceProcessStartInMs(uint64_t* aResult) {
task_power_info_v2_data_t task_power_info;
mach_msg_type_number_t count = TASK_POWER_INFO_V2_COUNT;
kern_return_t kr =
task_info(mach_task_self(), TASK_POWER_INFO_V2, (task_info_t)&task_power_info, &count);
kern_return_t kr = task_info(mach_task_self(), TASK_POWER_INFO_V2,
(task_info_t)&task_power_info, &count);
if (kr != KERN_SUCCESS) {
return NS_ERROR_FAILURE;
}
@ -59,7 +60,8 @@ nsresult GetGpuTimeSinceProcessStartInMs(uint64_t* aResult) {
int GetCycleTimeFrequencyMHz() { return 0; }
ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&& aRequests) {
ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
nsTArray<ProcInfoRequest>&& aRequests) {
ProcInfoPromise::ResolveOrRejectValue result;
HashMap<base::ProcessId, ProcInfo> gathered;
@ -81,14 +83,16 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
info.utilityActors = std::move(request.utilityInfo);
struct proc_taskinfo pti;
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTASKINFO, 0, &pti, PROC_PIDTASKINFO_SIZE) <
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTASKINFO, 0, &pti,
PROC_PIDTASKINFO_SIZE) <
PROC_PIDTASKINFO_SIZE) {
// Can't read data for this process.
// Probably either a sandboxing issue or a race condition, e.g.
// the process has been just been killed. Regardless, skip process.
continue;
}
info.cpuTime = (pti.pti_total_user + pti.pti_total_system) * timebase.numer / timebase.denom;
info.cpuTime = (pti.pti_total_user + pti.pti_total_system) *
timebase.numer / timebase.denom;
mach_port_t selectedTask;
// If we did not get a task from a child process, we use mach_task_self()
@ -102,7 +106,8 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
// matches the value in the 'Memory' column of the Activity Monitor.
task_vm_info_data_t task_vm_info;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
kern_return_t kr = task_info(selectedTask, TASK_VM_INFO, (task_info_t)&task_vm_info, &count);
kern_return_t kr = task_info(selectedTask, TASK_VM_INFO,
(task_info_t)&task_vm_info, &count);
info.memory = kr == KERN_SUCCESS ? task_vm_info.phys_footprint : 0;
// Now getting threads info
@ -123,8 +128,8 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
}
// Deallocate the thread list.
// Note that this deallocation is entirely undocumented, so the following code is based
// on guesswork and random examples found on the web.
// Note that this deallocation is entirely undocumented, so the following
// code is based on guesswork and random examples found on the web.
auto guardThreadCount = MakeScopeExit([&] {
if (threadList == nullptr) {
return;
@ -141,8 +146,8 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
// Basic thread info.
thread_extended_info_data_t threadInfoData;
count = THREAD_EXTENDED_INFO_COUNT;
kret =
thread_info(threadList[i], THREAD_EXTENDED_INFO, (thread_info_t)&threadInfoData, &count);
kret = thread_info(threadList[i], THREAD_EXTENDED_INFO,
(thread_info_t)&threadInfoData, &count);
if (kret != KERN_SUCCESS) {
continue;
}
@ -150,8 +155,8 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
// Getting the thread id.
thread_identifier_info identifierInfo;
count = THREAD_IDENTIFIER_INFO_COUNT;
kret = thread_info(threadList[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifierInfo,
&count);
kret = thread_info(threadList[i], THREAD_IDENTIFIER_INFO,
(thread_info_t)&identifierInfo, &count);
if (kret != KERN_SUCCESS) {
continue;
}
@ -162,7 +167,8 @@ ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(nsTArray<ProcInfoRequest>&
result.SetReject(NS_ERROR_OUT_OF_MEMORY);
return result;
}
thread->cpuTime = threadInfoData.pth_user_time + threadInfoData.pth_system_time;
thread->cpuTime =
threadInfoData.pth_user_time + threadInfoData.pth_system_time;
thread->name.AssignASCII(threadInfoData.pth_name);
thread->tid = identifierInfo.thread_id;
}

Просмотреть файл

@ -18,21 +18,21 @@ using namespace mozilla;
nsresult nsMacRemoteClient::Init() { return NS_OK; }
nsresult nsMacRemoteClient::SendCommandLine(const char* aProgram, const char* aProfile,
int32_t argc, char** argv,
const char* aDesktopStartupID, char** aResponse,
bool* aSucceeded) {
nsresult nsMacRemoteClient::SendCommandLine(
const char* aProgram, const char* aProfile, int32_t argc, char** argv,
const char* aDesktopStartupID, char** aResponse, bool* aSucceeded) {
mozilla::MacAutoreleasePool pool;
*aSucceeded = false;
nsString className;
BuildClassName(aProgram, aProfile, className);
NSString* serverNameString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(className.get())
length:className.Length()];
NSString* serverNameString = [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(className.get())
length:className.Length()];
CFMessagePortRef messageServer = CFMessagePortCreateRemote(0, (CFStringRef)serverNameString);
CFMessagePortRef messageServer =
CFMessagePortCreateRemote(0, (CFStringRef)serverNameString);
if (messageServer) {
// Getting current process directory
@ -48,7 +48,8 @@ nsresult nsMacRemoteClient::SendCommandLine(const char* aProgram, const char* aP
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:dict];
CFMessagePortSendRequest(messageServer, 0, (CFDataRef)data, 10.0, 0.0, NULL, NULL);
CFMessagePortSendRequest(messageServer, 0, (CFDataRef)data, 10.0, 0.0, NULL,
NULL);
CFMessagePortInvalidate(messageServer);
CFRelease(messageServer);

Просмотреть файл

@ -22,20 +22,22 @@
#include "nsXPCOM.h"
#include "RemoteUtils.h"
CFDataRef messageServerCallback(CFMessagePortRef aLocal, int32_t aMsgid, CFDataRef aData,
void* aInfo) {
CFDataRef messageServerCallback(CFMessagePortRef aLocal, int32_t aMsgid,
CFDataRef aData, void* aInfo) {
// One of the clients submitted a structure.
static_cast<nsMacRemoteServer*>(aInfo)->HandleCommandLine(aData);
return NULL;
}
// aData contains serialized Dictionary, which in turn contains command line arguments
// aData contains serialized Dictionary, which in turn contains command line
// arguments
void nsMacRemoteServer::HandleCommandLine(CFDataRef aData) {
mozilla::MacAutoreleasePool pool;
if (aData) {
NSDictionary* dict = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData*)aData];
NSDictionary* dict =
[NSKeyedUnarchiver unarchiveObjectWithData:(NSData*)aData];
if (dict && [dict isKindOfClass:[NSDictionary class]]) {
NSArray* args = dict[@"args"];
if (!args) {
@ -54,7 +56,8 @@ void nsMacRemoteServer::HandleCommandLine(CFDataRef aData) {
argv[i] = arg;
}
nsresult rv = cmdLine->Init(argc, argv, nullptr, nsICommandLine::STATE_REMOTE_AUTO);
nsresult rv =
cmdLine->Init(argc, argv, nullptr, nsICommandLine::STATE_REMOTE_AUTO);
// Cleaning up C array.
delete[] argv;
@ -75,21 +78,22 @@ void nsMacRemoteServer::HandleCommandLine(CFDataRef aData) {
}
}
nsresult nsMacRemoteServer::Startup(const char* aAppName, const char* aProfileName) {
nsresult nsMacRemoteServer::Startup(const char* aAppName,
const char* aProfileName) {
// This is the first instance ever.
// Let's register a notification listener here,
// In case future instances would want to notify us about command line arguments
// passed to them. Note, that if mozilla process is restarting, we still need to
// register for notifications.
// In case future instances would want to notify us about command line
// arguments passed to them. Note, that if mozilla process is restarting, we
// still need to register for notifications.
mozilla::MacAutoreleasePool pool;
nsString className;
BuildClassName(aAppName, aProfileName, className);
NSString* serverNameString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(className.get())
length:className.Length()];
NSString* serverNameString = [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(className.get())
length:className.Length()];
CFMessagePortContext context;
context.copyDescription = NULL;
@ -97,8 +101,9 @@ nsresult nsMacRemoteServer::Startup(const char* aAppName, const char* aProfileNa
context.release = NULL;
context.retain = NULL;
context.version = NULL;
mMessageServer = CFMessagePortCreateLocal(NULL, (CFStringRef)serverNameString,
messageServerCallback, &context, NULL);
mMessageServer =
CFMessagePortCreateLocal(NULL, (CFStringRef)serverNameString,
messageServerCallback, &context, NULL);
if (!mMessageServer) {
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -61,7 +61,8 @@ static bool RestartApplication() {
// Set spawn attributes.
size_t attr_count = sizeof(pref_cpu_types) / sizeof(pref_cpu_types[0]);
size_t attr_ocount = 0;
if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, pref_cpu_types, &attr_ocount) != 0 ||
if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, pref_cpu_types,
&attr_ocount) != 0 ||
attr_ocount != attr_count) {
posix_spawnattr_destroy(&spawnattr);
return false;
@ -89,7 +90,8 @@ static bool RestartApplication() {
gUI = self;
[mWindow center];
[mWindow setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]];
[mWindow setTitle:[[NSBundle mainBundle]
objectForInfoDictionaryKey:@"CFBundleName"]];
[NSApp activateIgnoringOtherApps:YES];
}
@ -189,7 +191,9 @@ static bool RestartApplication() {
[self setView:mErrorView animate:NO];
[mErrorHeaderLabel setStringValue:Str(ST_CRASHREPORTERHEADER)];
[self setStringFitVertically:mErrorLabel string:NSSTR(message) resizeWindow:YES];
[self setStringFitVertically:mErrorLabel
string:NSSTR(message)
resizeWindow:YES];
[mErrorCloseButton setTitle:Str(ST_OK)];
[mErrorCloseButton setKeyEquivalent:@"\r"];
@ -199,19 +203,22 @@ static bool RestartApplication() {
- (void)showReportInfo {
NSDictionary* boldAttr = @{
NSFontAttributeName : [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]],
NSFontAttributeName :
[NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]],
NSForegroundColorAttributeName : NSColor.textColor,
};
NSDictionary* normalAttr = @{
NSFontAttributeName : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]],
NSFontAttributeName :
[NSFont systemFontOfSize:[NSFont smallSystemFontSize]],
NSForegroundColorAttributeName : NSColor.textColor,
};
[mViewReportTextView setString:@""];
for (Json::ValueConstIterator iter = gQueryParameters.begin(); iter != gQueryParameters.end();
++iter) {
NSAttributedString* key = [[NSAttributedString alloc] initWithString:NSSTR(iter.name() + ": ")
attributes:boldAttr];
for (Json::ValueConstIterator iter = gQueryParameters.begin();
iter != gQueryParameters.end(); ++iter) {
NSAttributedString* key =
[[NSAttributedString alloc] initWithString:NSSTR(iter.name() + ": ")
attributes:boldAttr];
string str;
if (iter->isString()) {
str = iter->asString();
@ -220,24 +227,27 @@ static bool RestartApplication() {
builder["indentation"] = "";
str = writeString(builder, *iter);
}
NSAttributedString* value = [[NSAttributedString alloc] initWithString:NSSTR(str + "\n")
attributes:normalAttr];
NSAttributedString* value =
[[NSAttributedString alloc] initWithString:NSSTR(str + "\n")
attributes:normalAttr];
[[mViewReportTextView textStorage] appendAttributedString:key];
[[mViewReportTextView textStorage] appendAttributedString:value];
[key release];
[value release];
}
NSAttributedString* extra =
[[NSAttributedString alloc] initWithString:NSSTR("\n" + gStrings[ST_EXTRAREPORTINFO])
attributes:normalAttr];
NSAttributedString* extra = [[NSAttributedString alloc]
initWithString:NSSTR("\n" + gStrings[ST_EXTRAREPORTINFO])
attributes:normalAttr];
[[mViewReportTextView textStorage] appendAttributedString:extra];
[extra release];
}
- (void)maybeSubmitReport {
if ([mSubmitReportButton state] == NSOnState) {
[self setStringFitVertically:mProgressText string:Str(ST_REPORTDURINGSUBMIT) resizeWindow:YES];
[self setStringFitVertically:mProgressText
string:Str(ST_REPORTDURINGSUBMIT)
resizeWindow:YES];
// disable all the controls
[self enableControls:NO];
[mSubmitReportButton setEnabled:NO];
@ -258,7 +268,8 @@ static bool RestartApplication() {
- (IBAction)submitReportClicked:(id)sender {
[self updateSubmit];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:([mSubmitReportButton state] == NSOnState) forKey:@"submitReport"];
[userDefaults setBool:([mSubmitReportButton state] == NSOnState)
forKey:@"submitReport"];
[userDefaults synchronize];
}
@ -288,14 +299,16 @@ static bool RestartApplication() {
- (IBAction)includeURLClicked:(id)sender {
[self updateURL];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:([mIncludeURLButton state] == NSOnState) forKey:@"IncludeURL"];
[userDefaults setBool:([mIncludeURLButton state] == NSOnState)
forKey:@"IncludeURL"];
[userDefaults synchronize];
}
- (void)textDidChange:(NSNotification*)aNotification {
// update comment parameter
if ([[[mCommentText textStorage] mutableString] length] > 0)
gQueryParameters["Comments"] = [[[mCommentText textStorage] mutableString] UTF8String];
gQueryParameters["Comments"] =
[[[mCommentText textStorage] mutableString] UTF8String];
else
gQueryParameters.removeMember("Comments");
}
@ -308,7 +321,8 @@ static bool RestartApplication() {
if (([[aTextView string] lengthOfBytesUsingEncoding:NSUTF8StringEncoding] +
[replacementString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] -
[[[aTextView string] substringWithRange:affectedCharRange]
lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) > MAX_COMMENT_LENGTH) {
lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) >
MAX_COMMENT_LENGTH) {
return NO;
}
return YES;
@ -331,8 +345,8 @@ static bool RestartApplication() {
if (gRestartArgs.size() == 0) {
[mRestartButton removeFromSuperview];
if (!gRTLlayout) {
closeFrame.origin.x =
restartFrame.origin.x + (restartFrame.size.width - closeFrame.size.width);
closeFrame.origin.x = restartFrame.origin.x +
(restartFrame.size.width - closeFrame.size.width);
} else {
closeFrame.origin.x = restartFrame.origin.x;
}
@ -357,7 +371,8 @@ static bool RestartApplication() {
// possibly resize window if both buttons no longer fit
// leave 20 px from either side of the window, and 12 px
// between the buttons
float neededWidth = closeFrame.size.width + restartFrame.size.width + 2 * 20 + 12;
float neededWidth =
closeFrame.size.width + restartFrame.size.width + 2 * 20 + 12;
if (neededWidth > windowFrame.size.width) {
windowFrame.size.width = neededWidth;
@ -379,7 +394,8 @@ static bool RestartApplication() {
[checkbox setFrame:frame];
}
// keep existing spacing on left side, + 20 px spare on right
float neededWidth = frame.origin.x + checkbox.intrinsicContentSize.width + 20;
float neededWidth =
frame.origin.x + checkbox.intrinsicContentSize.width + 20;
if (neededWidth > windowFrame.size.width) {
windowFrame.size.width = neededWidth;
[mWindow setFrame:windowFrame display:true animate:NO];
@ -395,8 +411,9 @@ static bool RestartApplication() {
// now pin all the controls (except quit/submit) in place,
// if we lengthen the window after this, it's just to lengthen
// the progress text, so nothing above that text should move.
NSView* views[] = {mSubmitReportButton, mViewReportButton, mCommentScrollView,
mIncludeURLButton, mProgressIndicator, mProgressText};
NSView* views[] = {mSubmitReportButton, mViewReportButton,
mCommentScrollView, mIncludeURLButton,
mProgressIndicator, mProgressText};
for (auto view : views) {
[view setAutoresizingMask:NSViewMinYMargin];
}
@ -454,7 +471,9 @@ static bool RestartApplication() {
- (void)updateSubmit {
if ([mSubmitReportButton state] == NSOnState) {
[self setStringFitVertically:mProgressText string:Str(ST_REPORTPRESUBMIT) resizeWindow:YES];
[self setStringFitVertically:mProgressText
string:Str(ST_REPORTPRESUBMIT)
resizeWindow:YES];
[mProgressText setHidden:NO];
// enable all the controls
[self enableControls:YES];
@ -490,18 +509,24 @@ static bool RestartApplication() {
[NSApp terminate:self];
}
[self setStringFitVertically:mProgressText string:Str(ST_SUBMITFAILED) resizeWindow:YES];
[self setStringFitVertically:mProgressText
string:Str(ST_SUBMITFAILED)
resizeWindow:YES];
// quit after 5 seconds
[self performSelector:@selector(closeMeDown:) withObject:nil afterDelay:5.0];
[self performSelector:@selector(closeMeDown:)
withObject:nil
afterDelay:5.0];
}
[NSThread detachNewThreadSelector:@selector(uploadThread:) toTarget:self withObject:mPost];
[NSThread detachNewThreadSelector:@selector(uploadThread:)
toTarget:self
withObject:mPost];
}
- (bool)setupPost {
NSURL* url =
[NSURL URLWithString:[NSSTR(gSendURL)
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL* url = [NSURL
URLWithString:[NSSTR(gSendURL) stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding]];
if (!url) return false;
mPost = [[HTTPMultipartUpload alloc] initWithURL:url];
@ -514,7 +539,8 @@ static bool RestartApplication() {
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
string output = writeString(builder, gQueryParameters).append("\r\n");
NSMutableString* parameters = [[NSMutableString alloc] initWithUTF8String:output.c_str()];
NSMutableString* parameters =
[[NSMutableString alloc] initWithUTF8String:output.c_str()];
[mPost setParameters:parameters];
[parameters release];
@ -535,7 +561,8 @@ static bool RestartApplication() {
// if data is nil, we probably logged an error in uploadThread
if (data != nil && response != nil) {
ostringstream message;
message << "Crash report submission failed: server returned status " << [response statusCode];
message << "Crash report submission failed: server returned status "
<< [response statusCode];
LogMessage(message.str());
}
} else {
@ -563,9 +590,13 @@ static bool RestartApplication() {
[mProgressIndicator stopAnimation:self];
if (success) {
[self setStringFitVertically:mProgressText string:Str(ST_REPORTSUBMITSUCCESS) resizeWindow:YES];
[self setStringFitVertically:mProgressText
string:Str(ST_REPORTSUBMITSUCCESS)
resizeWindow:YES];
} else {
[self setStringFitVertically:mProgressText string:Str(ST_SUBMITFAILED) resizeWindow:YES];
[self setStringFitVertically:mProgressText
string:Str(ST_SUBMITFAILED)
resizeWindow:YES];
}
// quit after 5 seconds
[self performSelector:@selector(closeMeDown:) withObject:nil afterDelay:5.0];
@ -582,13 +613,16 @@ static bool RestartApplication() {
LogMessage("Crash report submission failed: " + message);
}
[self performSelectorOnMainThread:@selector(uploadComplete:) withObject:data waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(uploadComplete:)
withObject:data
waitUntilDone:YES];
[autoreleasepool release];
}
// to get auto-quit when we close the window
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication {
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:
(NSApplication*)theApplication {
return YES;
}
@ -621,10 +655,12 @@ static bool RestartApplication() {
- (void)setPlaceholder:(NSString*)placeholder {
NSColor* txtColor = [NSColor disabledControlTextColor];
NSDictionary* txtDict =
[NSDictionary dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName, nil];
mPlaceHolderString = [[NSMutableAttributedString alloc] initWithString:placeholder
attributes:txtDict];
NSDictionary* txtDict = [NSDictionary
dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName,
nil];
mPlaceHolderString =
[[NSMutableAttributedString alloc] initWithString:placeholder
attributes:txtDict];
if (gRTLlayout)
[mPlaceHolderString setAlignment:NSTextAlignmentRight
range:NSMakeRange(0, [placeholder length])];
@ -649,9 +685,11 @@ static bool RestartApplication() {
txtColor = [NSColor textColor];
else
txtColor = [NSColor disabledControlTextColor];
NSDictionary* txtDict =
[NSDictionary dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName, nil];
colorString = [[NSAttributedString alloc] initWithString:[self string] attributes:txtDict];
NSDictionary* txtDict = [NSDictionary
dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName,
nil];
colorString = [[NSAttributedString alloc] initWithString:[self string]
attributes:txtDict];
[[self textStorage] setAttributedString:colorString];
[self setInsertionPointColor:txtColor];
[colorString release];
@ -671,14 +709,16 @@ bool UIInit() {
gMainPool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
if (gStrings.find("isRTL") != gStrings.end() && gStrings["isRTL"] == "yes") gRTLlayout = true;
if (gStrings.find("isRTL") != gStrings.end() && gStrings["isRTL"] == "yes")
gRTLlayout = true;
if (gAutoSubmit) {
gUI = [[CrashReporterUI alloc] init];
} else {
[[NSBundle mainBundle] loadNibNamed:(gRTLlayout ? @"MainMenuRTL" : @"MainMenu")
owner:NSApp
topLevelObjects:nil];
[[NSBundle mainBundle]
loadNibNamed:(gRTLlayout ? @"MainMenuRTL" : @"MainMenu")
owner:NSApp
topLevelObjects:nil];
}
return true;
@ -724,9 +764,10 @@ bool UIGetIniPath(string& path) {
return true;
}
bool UIGetSettingsPath(const string& vendor, const string& product, string& settingsPath) {
NSArray* paths =
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
bool UIGetSettingsPath(const string& vendor, const string& product,
string& settingsPath) {
NSArray* paths = NSSearchPathForDirectoriesInDomains(
NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString* destPath = [paths firstObject];
// Note that MacOS ignores the vendor when creating the profile hierarchy -
@ -751,10 +792,12 @@ bool UIMoveFile(const string& file, const string& newfile) {
if (errno != EXDEV) return false;
NSFileManager* fileManager = [NSFileManager defaultManager];
NSString* source = [fileManager stringWithFileSystemRepresentation:file.c_str()
length:file.length()];
NSString* dest = [fileManager stringWithFileSystemRepresentation:newfile.c_str()
length:newfile.length()];
NSString* source =
[fileManager stringWithFileSystemRepresentation:file.c_str()
length:file.length()];
NSString* dest =
[fileManager stringWithFileSystemRepresentation:newfile.c_str()
length:newfile.length()];
if (!source || !dest) return false;
[fileManager moveItemAtPath:source toPath:dest error:NULL];

Просмотреть файл

@ -55,7 +55,8 @@ bool IsBinaryArmExecutable(const char* executablePath) {
bool isArmExecutable = false;
CFURLRef url = ::CFURLCreateFromFileSystemRepresentation(
kCFAllocatorDefault, (const UInt8*)executablePath, strlen(executablePath), false);
kCFAllocatorDefault, (const UInt8*)executablePath, strlen(executablePath),
false);
if (!url) {
return false;
}
@ -68,7 +69,8 @@ bool IsBinaryArmExecutable(const char* executablePath) {
CFIndex archCount = ::CFArrayGetCount(archs);
for (CFIndex i = 0; i < archCount; i++) {
CFNumberRef currentArch = static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(archs, i));
CFNumberRef currentArch =
static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(archs, i));
int currentArchInt = 0;
if (!::CFNumberGetValue(currentArch, kCFNumberIntType, &currentArchInt)) {
continue;
@ -161,7 +163,8 @@ void LaunchMacPostProcess(const char* aAppBundle) {
// Launch helper to perform post processing for the update; this is the Mac
// analogue of LaunchWinPostProcess (PostUpdateWin).
NSString* iniPath = [NSString stringWithUTF8String:aAppBundle];
iniPath = [iniPath stringByAppendingPathComponent:@"Contents/Resources/updater.ini"];
iniPath = [iniPath
stringByAppendingPathComponent:@"Contents/Resources/updater.ini"];
NSFileManager* fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:iniPath]) {
@ -171,8 +174,8 @@ void LaunchMacPostProcess(const char* aAppBundle) {
int readResult;
mozilla::UniquePtr<char[]> values[2];
readResult =
ReadStrings([iniPath UTF8String], "ExeRelPath\0ExeArg\0", 2, values, "PostUpdateMac");
readResult = ReadStrings([iniPath UTF8String], "ExeRelPath\0ExeArg\0", 2,
values, "PostUpdateMac");
if (readResult) {
return;
}
@ -194,7 +197,8 @@ void LaunchMacPostProcess(const char* aAppBundle) {
exeFullPath = [exeFullPath stringByAppendingPathComponent:exeRelPath];
mozilla::UniquePtr<char[]> optVal;
readResult = ReadStrings([iniPath UTF8String], "ExeAsync\0", 1, &optVal, "PostUpdateMac");
readResult = ReadStrings([iniPath UTF8String], "ExeAsync\0", 1, &optVal,
"PostUpdateMac");
NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:exeFullPath];
@ -223,8 +227,10 @@ id ConnectToUpdateServer() {
updateServer = (id)[NSConnection
rootProxyForConnectionWithRegisteredName:@"org.mozilla.updater.server"
host:nil
usingNameServer:[NSSocketPortNameServer sharedInstance]];
if (!updateServer || ![updateServer respondsToSelector:@selector(abort)] ||
usingNameServer:[NSSocketPortNameServer
sharedInstance]];
if (!updateServer ||
![updateServer respondsToSelector:@selector(abort)] ||
![updateServer respondsToSelector:@selector(getArguments)] ||
![updateServer respondsToSelector:@selector(shutdown)]) {
NSLog(@"Server doesn't exist or doesn't provide correct selectors.");
@ -262,9 +268,13 @@ void CleanupElevatedMacUpdate(bool aFailureOccurred) {
}
NSFileManager* manager = [NSFileManager defaultManager];
[manager removeItemAtPath:@"/Library/PrivilegedHelperTools/org.mozilla.updater" error:nil];
[manager removeItemAtPath:@"/Library/LaunchDaemons/org.mozilla.updater.plist" error:nil];
const char* launchctlArgs[] = {"/bin/launchctl", "remove", "org.mozilla.updater"};
[manager
removeItemAtPath:@"/Library/PrivilegedHelperTools/org.mozilla.updater"
error:nil];
[manager removeItemAtPath:@"/Library/LaunchDaemons/org.mozilla.updater.plist"
error:nil];
const char* launchctlArgs[] = {"/bin/launchctl", "remove",
"org.mozilla.updater"};
// The following call will terminate the current process due to the "remove"
// argument in launchctlArgs.
LaunchChild(3, launchctlArgs);
@ -282,13 +292,15 @@ bool ObtainUpdaterArguments(int* argc, char*** argv) {
}
@try {
NSArray* updaterArguments = [updateServer performSelector:@selector(getArguments)];
NSArray* updaterArguments =
[updateServer performSelector:@selector(getArguments)];
*argc = [updaterArguments count];
char** tempArgv = (char**)malloc(sizeof(char*) * (*argc));
for (int i = 0; i < *argc; i++) {
int argLen = [[updaterArguments objectAtIndex:i] length] + 1;
tempArgv[i] = (char*)malloc(argLen);
strncpy(tempArgv[i], [[updaterArguments objectAtIndex:i] UTF8String], argLen);
strncpy(tempArgv[i], [[updaterArguments objectAtIndex:i] UTF8String],
argLen);
}
*argv = tempArgv;
} @catch (NSException* e) {
@ -334,7 +346,8 @@ bool ObtainUpdaterArguments(int* argc, char*** argv) {
- (BOOL)runServer {
NSPort* serverPort = [NSSocketPort port];
NSConnection* server = [NSConnection connectionWithReceivePort:serverPort sendPort:serverPort];
NSConnection* server = [NSConnection connectionWithReceivePort:serverPort
sendPort:serverPort];
[server setRootObject:self];
if ([server registerName:@"org.mozilla.updater.server"
withNameServer:[NSSocketPortNameServer sharedInstance]] == NO) {
@ -343,8 +356,9 @@ bool ObtainUpdaterArguments(int* argc, char*** argv) {
return NO;
}
while ([self shouldKeepRunning] && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]])
while ([self shouldKeepRunning] &&
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]])
;
return ![self wasAborted];
}
@ -394,9 +408,11 @@ bool IsOwnedByGroupAdmin(const char* aAppBundle) {
NSString* appDir = [NSString stringWithUTF8String:aAppBundle];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSDictionary* attributes = [fileManager attributesOfItemAtPath:appDir error:nil];
NSDictionary* attributes = [fileManager attributesOfItemAtPath:appDir
error:nil];
bool isOwnedByAdmin = false;
if (attributes && [[attributes valueForKey:NSFileGroupOwnerAccountID] intValue] == 80) {
if (attributes &&
[[attributes valueForKey:NSFileGroupOwnerAccountID] intValue] == 80) {
isOwnedByAdmin = true;
}
return isOwnedByAdmin;
@ -425,13 +441,14 @@ void SetGroupOwnershipAndPermissions(const char* aAppBundle) {
return;
}
NSArray* permKeys =
[NSArray arrayWithObjects:NSFileGroupOwnerAccountID, NSFilePosixPermissions, nil];
NSArray* permKeys = [NSArray
arrayWithObjects:NSFileGroupOwnerAccountID, NSFilePosixPermissions, nil];
// For all descendants of Firefox.app, set group ownership to 80 ("admin") and
// ensure write permission for the group.
for (NSString* currPath in paths) {
NSString* child = [appDir stringByAppendingPathComponent:currPath];
NSDictionary* oldAttributes = [fileManager attributesOfItemAtPath:child error:&error];
NSDictionary* oldAttributes = [fileManager attributesOfItemAtPath:child
error:&error];
if (error) {
return;
}
@ -440,12 +457,20 @@ void SetGroupOwnershipAndPermissions(const char* aAppBundle) {
if ([oldAttributes fileType] == NSFileTypeSymbolicLink) {
continue;
}
NSNumber* oldPerms = (NSNumber*)[oldAttributes valueForKey:NSFilePosixPermissions];
NSNumber* oldPerms =
(NSNumber*)[oldAttributes valueForKey:NSFilePosixPermissions];
NSArray* permObjects = [NSArray
arrayWithObjects:[NSNumber numberWithUnsignedLong:80],
[NSNumber numberWithUnsignedLong:[oldPerms shortValue] | 020], nil];
NSDictionary* attributes = [NSDictionary dictionaryWithObjects:permObjects forKeys:permKeys];
if (![fileManager setAttributes:attributes ofItemAtPath:child error:&error] || error) {
[NSNumber
numberWithUnsignedLong:[oldPerms shortValue] |
020],
nil];
NSDictionary* attributes = [NSDictionary dictionaryWithObjects:permObjects
forKeys:permKeys];
if (![fileManager setAttributes:attributes
ofItemAtPath:child
error:&error] ||
error) {
return;
}
}
@ -483,7 +508,9 @@ bool PerformInstallationFromDMG(int argc, char** argv) {
}
NSString* bundlePath = [NSString stringWithUTF8String:argv[2]];
NSString* destPath = [NSString stringWithUTF8String:argv[3]];
if ([[NSFileManager defaultManager] copyItemAtPath:bundlePath toPath:destPath error:nil]) {
if ([[NSFileManager defaultManager] copyItemAtPath:bundlePath
toPath:destPath
error:nil]) {
RegisterAppWithLaunchServices(destPath);
StripQuarantineBit(destPath);
return true;

Просмотреть файл

@ -32,12 +32,14 @@ static const char* sUpdatePath;
NSWindow* w = [progressBar window];
[w setTitle:[NSString stringWithUTF8String:sLabels.title.get()]];
[progressTextField setStringValue:[NSString stringWithUTF8String:sLabels.info.get()]];
[progressTextField
setStringValue:[NSString stringWithUTF8String:sLabels.info.get()]];
NSRect origTextFrame = [progressTextField frame];
[progressTextField sizeToFit];
int widthAdjust = progressTextField.frame.size.width - origTextFrame.size.width;
int widthAdjust =
progressTextField.frame.size.width - origTextFrame.size.width;
if (widthAdjust > 0) {
NSRect f;
@ -118,7 +120,9 @@ int ShowProgressUI(bool indeterminate) {
sIndeterminate = indeterminate;
[NSApplication sharedApplication];
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp topLevelObjects:nil];
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:nil];
[NSApp run];
return 0;

Просмотреть файл

@ -34,8 +34,8 @@ class nsOSXSystemProxySettings : public nsISystemProxySettings {
nsresult GetAutoconfigURL(nsAutoCString& aResult) const;
// Find the SystemConfiguration proxy & port for a given URI
nsresult FindSCProxyPort(const nsACString& aScheme, nsACString& aResultHost, int32_t& aResultPort,
bool& aResultSocksProxy);
nsresult FindSCProxyPort(const nsACString& aScheme, nsACString& aResultHost,
int32_t& aResultPort, bool& aResultSocksProxy);
// is host:port on the proxy exception list?
bool IsInExceptionList(const nsACString& aHost) const;
@ -69,22 +69,26 @@ nsOSXSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) {
}
// Mapping of URI schemes to SystemConfiguration keys
const nsOSXSystemProxySettings::SchemeMapping nsOSXSystemProxySettings::gSchemeMappingList[] = {
{"http", kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort,
false},
{"https", kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy, kSCPropNetProxiesHTTPSPort,
false},
{"ftp", kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy, kSCPropNetProxiesFTPPort, false},
{"socks", kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort,
true},
{NULL, NULL, NULL, NULL, false},
const nsOSXSystemProxySettings::SchemeMapping
nsOSXSystemProxySettings::gSchemeMappingList[] = {
{"http", kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy,
kSCPropNetProxiesHTTPPort, false},
{"https", kSCPropNetProxiesHTTPSEnable, kSCPropNetProxiesHTTPSProxy,
kSCPropNetProxiesHTTPSPort, false},
{"ftp", kSCPropNetProxiesFTPEnable, kSCPropNetProxiesFTPProxy,
kSCPropNetProxiesFTPPort, false},
{"socks", kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy,
kSCPropNetProxiesSOCKSPort, true},
{NULL, NULL, NULL, NULL, false},
};
static void ProxyHasChangedWrapper(SCDynamicStoreRef aStore, CFArrayRef aChangedKeys, void* aInfo) {
static void ProxyHasChangedWrapper(SCDynamicStoreRef aStore,
CFArrayRef aChangedKeys, void* aInfo) {
static_cast<nsOSXSystemProxySettings*>(aInfo)->ProxyHasChanged();
}
nsOSXSystemProxySettings::nsOSXSystemProxySettings() : mSystemDynamicStore(NULL), mProxyDict(NULL) {
nsOSXSystemProxySettings::nsOSXSystemProxySettings()
: mSystemDynamicStore(NULL), mProxyDict(NULL) {
mContext = (SCDynamicStoreContext){0, this, NULL, NULL, NULL};
}
@ -94,15 +98,16 @@ nsresult nsOSXSystemProxySettings::Init() {
// Register for notification of proxy setting changes
// See:
// http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/CFStreamTasks/chapter_4_section_5.html
mSystemDynamicStore =
SCDynamicStoreCreate(NULL, CFSTR("Mozilla"), ProxyHasChangedWrapper, &mContext);
mSystemDynamicStore = SCDynamicStoreCreate(NULL, CFSTR("Mozilla"),
ProxyHasChangedWrapper, &mContext);
if (!mSystemDynamicStore) return NS_ERROR_FAILURE;
// Set up the store to monitor any changes to the proxies
CFStringRef proxiesKey = SCDynamicStoreKeyCreateProxies(NULL);
if (!proxiesKey) return NS_ERROR_FAILURE;
CFArrayRef keyArray = CFArrayCreate(NULL, (const void**)(&proxiesKey), 1, &kCFTypeArrayCallBacks);
CFArrayRef keyArray = CFArrayCreate(NULL, (const void**)(&proxiesKey), 1,
&kCFTypeArrayCallBacks);
CFRelease(proxiesKey);
if (!keyArray) return NS_ERROR_FAILURE;
@ -113,7 +118,8 @@ nsresult nsOSXSystemProxySettings::Init() {
CFRunLoopSourceRef storeRLSource =
SCDynamicStoreCreateRunLoopSource(NULL, mSystemDynamicStore, 0);
if (!storeRLSource) return NS_ERROR_FAILURE;
CFRunLoopAddSource(CFRunLoopGetCurrent(), storeRLSource, kCFRunLoopCommonModes);
CFRunLoopAddSource(CFRunLoopGetCurrent(), storeRLSource,
kCFRunLoopCommonModes);
CFRelease(storeRLSource);
// Load the initial copy of proxy info
@ -135,7 +141,8 @@ nsOSXSystemProxySettings::~nsOSXSystemProxySettings() {
if (mSystemDynamicStore) {
// Invalidate the dynamic store's run loop source
// to get the store out of the run loop
CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, mSystemDynamicStore, 0);
CFRunLoopSourceRef rls =
SCDynamicStoreCreateRunLoopSource(NULL, mSystemDynamicStore, 0);
if (rls) {
CFRunLoopSourceInvalidate(rls);
CFRelease(rls);
@ -158,20 +165,24 @@ void nsOSXSystemProxySettings::ProxyHasChanged() {
}
nsresult nsOSXSystemProxySettings::FindSCProxyPort(const nsACString& aScheme,
nsACString& aResultHost, int32_t& aResultPort,
nsACString& aResultHost,
int32_t& aResultPort,
bool& aResultSocksProxy) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NS_ENSURE_TRUE(mProxyDict != NULL, NS_ERROR_FAILURE);
for (const SchemeMapping* keys = gSchemeMappingList; keys->mScheme != NULL; ++keys) {
for (const SchemeMapping* keys = gSchemeMappingList; keys->mScheme != NULL;
++keys) {
// Check for matching scheme (when appropriate)
if (strcasecmp(keys->mScheme, PromiseFlatCString(aScheme).get()) && !keys->mIsSocksProxy)
if (strcasecmp(keys->mScheme, PromiseFlatCString(aScheme).get()) &&
!keys->mIsSocksProxy)
continue;
// Check the proxy is enabled
NSNumber* enabled = [mProxyDict objectForKey:(NSString*)keys->mEnabled];
NS_ENSURE_TRUE(enabled == NULL || [enabled isKindOfClass:[NSNumber class]], NS_ERROR_FAILURE);
NS_ENSURE_TRUE(enabled == NULL || [enabled isKindOfClass:[NSNumber class]],
NS_ERROR_FAILURE);
if ([enabled intValue] == 0) continue;
// Get the proxy host
@ -198,17 +209,21 @@ nsresult nsOSXSystemProxySettings::FindSCProxyPort(const nsACString& aScheme,
bool nsOSXSystemProxySettings::IsAutoconfigEnabled() const {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSNumber* value = [mProxyDict objectForKey:(NSString*)kSCPropNetProxiesProxyAutoConfigEnable];
NS_ENSURE_TRUE(value == NULL || [value isKindOfClass:[NSNumber class]], false);
NSNumber* value = [mProxyDict
objectForKey:(NSString*)kSCPropNetProxiesProxyAutoConfigEnable];
NS_ENSURE_TRUE(value == NULL || [value isKindOfClass:[NSNumber class]],
false);
return ([value intValue] != 0);
NS_OBJC_END_TRY_BLOCK_RETURN(false);
}
nsresult nsOSXSystemProxySettings::GetAutoconfigURL(nsAutoCString& aResult) const {
nsresult nsOSXSystemProxySettings::GetAutoconfigURL(
nsAutoCString& aResult) const {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSString* value = [mProxyDict objectForKey:(NSString*)kSCPropNetProxiesProxyAutoConfigURLString];
NSString* value = [mProxyDict
objectForKey:(NSString*)kSCPropNetProxiesProxyAutoConfigURLString];
if (value != NULL) {
NS_ENSURE_TRUE([value isKindOfClass:[NSString class]], NS_ERROR_FAILURE);
aResult.Assign([value UTF8String]);
@ -220,20 +235,25 @@ nsresult nsOSXSystemProxySettings::GetAutoconfigURL(nsAutoCString& aResult) cons
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
bool nsOSXSystemProxySettings::IsInExceptionList(const nsACString& aHost) const {
bool nsOSXSystemProxySettings::IsInExceptionList(
const nsACString& aHost) const {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NS_ENSURE_TRUE(mProxyDict != NULL, false);
NSArray* exceptionList = [mProxyDict objectForKey:(NSString*)kSCPropNetProxiesExceptionsList];
NS_ENSURE_TRUE(exceptionList == NULL || [exceptionList isKindOfClass:[NSArray class]], false);
NSArray* exceptionList =
[mProxyDict objectForKey:(NSString*)kSCPropNetProxiesExceptionsList];
NS_ENSURE_TRUE(
exceptionList == NULL || [exceptionList isKindOfClass:[NSArray class]],
false);
NSEnumerator* exceptionEnumerator = [exceptionList objectEnumerator];
NSString* currentValue = NULL;
while ((currentValue = [exceptionEnumerator nextObject])) {
NS_ENSURE_TRUE([currentValue isKindOfClass:[NSString class]], false);
nsAutoCString overrideStr([currentValue UTF8String]);
if (mozilla::toolkit::system::IsHostProxyEntry(aHost, overrideStr)) return true;
if (mozilla::toolkit::system::IsHostProxyEntry(aHost, overrideStr))
return true;
}
NS_OBJC_END_TRY_BLOCK_RETURN(false);
@ -257,7 +277,8 @@ nsresult nsOSXSystemProxySettings::GetPACURI(nsACString& aResult) {
nsresult nsOSXSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
const nsACString& aScheme,
const nsACString& aHost, const int32_t aPort,
const nsACString& aHost,
const int32_t aPort,
nsACString& aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@ -283,7 +304,8 @@ using namespace mozilla::net;
class OSXSystemProxySettingsAsync final : public nsOSXSystemProxySettings {
public:
NS_INLINE_DECL_REFCOUNTING_INHERITED(OSXSystemProxySettingsAsync, nsOSXSystemProxySettings)
NS_INLINE_DECL_REFCOUNTING_INHERITED(OSXSystemProxySettingsAsync,
nsOSXSystemProxySettings)
NS_DECL_NSISYSTEMPROXYSETTINGS
OSXSystemProxySettingsAsync();
@ -314,7 +336,8 @@ void OSXSystemProxySettingsAsync::OnProxyConfigChangedInternal() {
}
// proxies (for now: PROXY and SOCKS)
for (const SchemeMapping* keys = gSchemeMappingList; keys->mScheme != NULL; ++keys) {
for (const SchemeMapping* keys = gSchemeMappingList; keys->mScheme != NULL;
++keys) {
// Check the proxy is enabled
NSNumber* enabled = [mProxyDict objectForKey:(NSString*)keys->mEnabled];
if (!(enabled == NULL || [enabled isKindOfClass:[NSNumber class]])) {
@ -342,17 +365,20 @@ void OSXSystemProxySettingsAsync::OnProxyConfigChangedInternal() {
}
int32_t resultPort = [port intValue];
ProxyServer server(ProxyConfig::ToProxyType(keys->mScheme), resultHost, resultPort);
ProxyServer server(ProxyConfig::ToProxyType(keys->mScheme), resultHost,
resultPort);
config.Rules().mProxyServers[server.Type()] = std::move(server);
}
// exceptions
NSArray* exceptionList = [mProxyDict objectForKey:(NSString*)kSCPropNetProxiesExceptionsList];
NSArray* exceptionList =
[mProxyDict objectForKey:(NSString*)kSCPropNetProxiesExceptionsList];
if (exceptionList != NULL && [exceptionList isKindOfClass:[NSArray class]]) {
NSEnumerator* exceptionEnumerator = [exceptionList objectEnumerator];
NSString* currentValue = NULL;
while ((currentValue = [exceptionEnumerator nextObject])) {
if (currentValue != NULL && [currentValue isKindOfClass:[NSString class]]) {
if (currentValue != NULL &&
[currentValue isKindOfClass:[NSString class]]) {
nsCString overrideStr([currentValue UTF8String]);
config.ByPassRules().mExceptions.AppendElement(std::move(overrideStr));
}
@ -374,8 +400,10 @@ OSXSystemProxySettingsAsync::GetPACURI(nsACString& aResult) {
}
NS_IMETHODIMP
OSXSystemProxySettingsAsync::GetProxyForURI(const nsACString& aSpec, const nsACString& aScheme,
const nsACString& aHost, const int32_t aPort,
OSXSystemProxySettingsAsync::GetProxyForURI(const nsACString& aSpec,
const nsACString& aScheme,
const nsACString& aHost,
const int32_t aPort,
nsACString& aResult) {
for (const auto& bypassRule : mConfig.ByPassRules().mExceptions) {
if (mozilla::toolkit::system::IsHostProxyEntry(aHost, bypassRule)) {
@ -389,9 +417,10 @@ OSXSystemProxySettingsAsync::GetProxyForURI(const nsACString& aSpec, const nsACS
}
NS_IMPL_COMPONENT_FACTORY(nsOSXSystemProxySettings) {
auto settings = mozilla::StaticPrefs::network_proxy_detect_system_proxy_changes()
? mozilla::MakeRefPtr<OSXSystemProxySettingsAsync>()
: mozilla::MakeRefPtr<nsOSXSystemProxySettings>();
auto settings =
mozilla::StaticPrefs::network_proxy_detect_system_proxy_changes()
? mozilla::MakeRefPtr<OSXSystemProxySettingsAsync>()
: mozilla::MakeRefPtr<nsOSXSystemProxySettings>();
if (NS_SUCCEEDED(settings->Init())) {
return settings.forget().downcast<nsISupports>();
}

Просмотреть файл

@ -5,8 +5,9 @@
// NSApplication delegate for Mac OS X Cocoa API.
// As of 10.4 Tiger, the system can send six kinds of Apple Events to an application;
// a well-behaved XUL app should have some kind of handling for all of them.
// As of 10.4 Tiger, the system can send six kinds of Apple Events to an
// application; a well-behaved XUL app should have some kind of handling for all
// of them.
//
// See
// http://developer.apple.com/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_handle_AEs/chapter_11_section_3.html
@ -92,7 +93,9 @@ void SetupMacApplicationDelegate(bool* gRestartedByOS) {
// This call makes it so that application:openFile: doesn't get bogus calls
// from Cocoa doing its own parsing of the argument string. And yes, we need
// to use a string with a boolean value in it. That's just how it works.
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
[[NSUserDefaults standardUserDefaults]
setObject:@"NO"
forKey:@"NSTreatUnknownArgumentsAsOpen"];
// Create the delegate. This should be around for the lifetime of the app.
id<NSApplicationDelegate> delegate = [[MacApplicationDelegate alloc] init];
@ -164,9 +167,11 @@ void ProcessPendingGetURLAppleEvents() {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
NSAppleEventManager* aeMgr = [NSAppleEventManager sharedAppleEventManager];
[aeMgr removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
[aeMgr removeEventHandlerForEventClass:kInternetEventClass
andEventID:kAEGetURL];
[aeMgr removeEventHandlerForEventClass:'WWW!' andEventID:'OURL'];
[aeMgr removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
[aeMgr removeEventHandlerForEventClass:kCoreEventClass
andEventID:kAEOpenDocuments];
[super dealloc];
NS_OBJC_END_TRY_IGNORE_BLOCK;
@ -175,7 +180,8 @@ void ProcessPendingGetURLAppleEvents() {
// The method that NSApplication calls upon a request to reopen, such as when
// the Dock icon is clicked and no windows are open. A "visible" window may be
// miniaturized, so we can't skip nsCocoaNativeReOpen() if 'flag' is 'true'.
- (BOOL)applicationShouldHandleReopen:(NSApplication*)theApp hasVisibleWindows:(BOOL)flag {
- (BOOL)applicationShouldHandleReopen:(NSApplication*)theApp
hasVisibleWindows:(BOOL)flag {
nsCOMPtr<nsINativeAppSupport> nas = NS_GetNativeAppSupport();
NS_ENSURE_TRUE(nas, NO);
@ -187,9 +193,10 @@ void ProcessPendingGetURLAppleEvents() {
return NO;
}
// The method that NSApplication calls when documents are requested to be opened.
// It will be called once for each selected document.
- (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename {
// The method that NSApplication calls when documents are requested to be
// opened. It will be called once for each selected document.
- (BOOL)application:(NSApplication*)theApplication
openFile:(NSString*)filename {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSURL* url = [NSURL fileURLWithPath:filename];
@ -199,10 +206,12 @@ void ProcessPendingGetURLAppleEvents() {
if (!urlString) return NO;
// Add the URL to any command line we're currently setting up.
if (CommandLineServiceMac::AddURLToCurrentCommandLine([urlString UTF8String])) return YES;
if (CommandLineServiceMac::AddURLToCurrentCommandLine([urlString UTF8String]))
return YES;
nsCOMPtr<nsILocalFileMac> inFile;
nsresult rv = NS_NewLocalFileWithCFURL((CFURLRef)url, true, getter_AddRefs(inFile));
nsresult rv =
NS_NewLocalFileWithCFURL((CFURLRef)url, true, getter_AddRefs(inFile));
if (NS_FAILED(rv)) return NO;
nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
@ -212,14 +221,16 @@ void ProcessPendingGetURLAppleEvents() {
if (NS_FAILED(rv)) return NO;
nsCOMPtr<nsIFile> workingDir;
rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR,
getter_AddRefs(workingDir));
if (NS_FAILED(rv)) {
// Couldn't find a working dir. Uh oh. Good job cmdline::Init can cope.
workingDir = nullptr;
}
const char* argv[3] = {nullptr, "-file", filePath.get()};
rv = cmdLine->Init(3, argv, workingDir, nsICommandLine::STATE_REMOTE_EXPLICIT);
rv =
cmdLine->Init(3, argv, workingDir, nsICommandLine::STATE_REMOTE_EXPLICIT);
if (NS_FAILED(rv)) return NO;
if (NS_SUCCEEDED(cmdLine->Run())) return YES;
@ -229,10 +240,11 @@ void ProcessPendingGetURLAppleEvents() {
NS_OBJC_END_TRY_BLOCK_RETURN(NO);
}
// The method that NSApplication calls when documents are requested to be printed
// from the Finder (under the "File" menu).
// It will be called once for each selected document.
- (BOOL)application:(NSApplication*)theApplication printFile:(NSString*)filename {
// The method that NSApplication calls when documents are requested to be
// printed from the Finder (under the "File" menu). It will be called once for
// each selected document.
- (BOOL)application:(NSApplication*)theApplication
printFile:(NSString*)filename {
return NO;
}
@ -256,7 +268,8 @@ void ProcessPendingGetURLAppleEvents() {
if (NS_FAILED(rv) || !dockMenuInterface) return menu;
RefPtr<mozilla::widget::NativeMenuMac> dockMenu =
static_cast<nsStandaloneNativeMenu*>(dockMenuInterface.get())->GetNativeMenu();
static_cast<nsStandaloneNativeMenu*>(dockMenuInterface.get())
->GetNativeMenu();
// Give the menu the opportunity to update itself before display.
dockMenu->MenuWillOpen();
@ -288,16 +301,21 @@ void ProcessPendingGetURLAppleEvents() {
- (void)applicationWillFinishLaunching:(NSNotification*)notification {
// We provide our own full screen menu item, so we don't want the OS providing
// one as well.
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
[[NSUserDefaults standardUserDefaults]
setBool:NO
forKey:@"NSFullScreenMenuItemEverywhere"];
}
// If we don't handle applicationShouldTerminate:, a call to [NSApp terminate:]
// (from the browser or from the OS) can result in an unclean shutdown.
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender {
nsCOMPtr<nsIObserverService> obsServ = do_GetService("@mozilla.org/observer-service;1");
- (NSApplicationTerminateReply)applicationShouldTerminate:
(NSApplication*)sender {
nsCOMPtr<nsIObserverService> obsServ =
do_GetService("@mozilla.org/observer-service;1");
if (!obsServ) return NSTerminateNow;
nsCOMPtr<nsISupportsPRBool> cancelQuit = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
nsCOMPtr<nsISupportsPRBool> cancelQuit =
do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
if (!cancelQuit) return NSTerminateNow;
cancelQuit->SetData(false);
@ -307,7 +325,8 @@ void ProcessPendingGetURLAppleEvents() {
cancelQuit->GetData(&abortQuit);
if (abortQuit) return NSTerminateCancel;
nsCOMPtr<nsIAppStartup> appService = do_GetService("@mozilla.org/toolkit/app-startup;1");
nsCOMPtr<nsIAppStartup> appService =
do_GetService("@mozilla.org/toolkit/app-startup;1");
if (appService) {
bool userAllowedQuit = true;
appService->Quit(nsIAppStartup::eForceQuit, 0, &userAllowedQuit);
@ -325,22 +344,28 @@ void ProcessPendingGetURLAppleEvents() {
AutoAutoreleasePool pool;
bool isGetURLEvent = ([event eventClass] == kInternetEventClass && [event eventID] == kAEGetURL);
bool isGetURLEvent = ([event eventClass] == kInternetEventClass &&
[event eventID] == kAEGetURL);
if (isGetURLEvent) sProcessedGetURLEvent = true;
if (isGetURLEvent || ([event eventClass] == 'WWW!' && [event eventID] == 'OURL')) {
NSString* urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
if (isGetURLEvent ||
([event eventClass] == 'WWW!' && [event eventID] == 'OURL')) {
NSString* urlString =
[[event paramDescriptorForKeyword:keyDirectObject] stringValue];
NSURL* url = [NSURL URLWithString:urlString];
[self openURL:url];
} else if ([event eventClass] == kCoreEventClass && [event eventID] == kAEOpenDocuments) {
NSAppleEventDescriptor* fileListDescriptor = [event paramDescriptorForKeyword:keyDirectObject];
} else if ([event eventClass] == kCoreEventClass &&
[event eventID] == kAEOpenDocuments) {
NSAppleEventDescriptor* fileListDescriptor =
[event paramDescriptorForKeyword:keyDirectObject];
if (!fileListDescriptor) return;
// Descriptor list indexing is one-based...
NSInteger numberOfFiles = [fileListDescriptor numberOfItems];
for (NSInteger i = 1; i <= numberOfFiles; i++) {
NSString* urlString = [[fileListDescriptor descriptorAtIndex:i] stringValue];
NSString* urlString =
[[fileListDescriptor descriptorAtIndex:i] stringValue];
if (!urlString) continue;
// We need a path, not a URL
@ -359,12 +384,15 @@ void ProcessPendingGetURLAppleEvents() {
- (BOOL)application:(NSApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
#if defined(MAC_OS_X_VERSION_10_14) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
restorationHandler:(void (^)(NSArray<id<NSUserActivityRestoring>>*))restorationHandler {
#if defined(MAC_OS_X_VERSION_10_14) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
restorationHandler:
(void (^)(NSArray<id<NSUserActivityRestoring>>*))restorationHandler {
#else
restorationHandler:(void (^)(NSArray*))restorationHandler {
#endif
if (![userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
if (![userActivity.activityType
isEqualToString:NSUserActivityTypeBrowsingWeb]) {
return NO;
}
@ -378,7 +406,8 @@ void ProcessPendingGetURLAppleEvents() {
}
- (BOOL)openURL:(NSURL*)url {
if (!url || !url.scheme || [url.scheme caseInsensitiveCompare:@"chrome"] == NSOrderedSame) {
if (!url || !url.scheme ||
[url.scheme caseInsensitiveCompare:@"chrome"] == NSOrderedSame) {
return NO;
}
@ -390,14 +419,16 @@ void ProcessPendingGetURLAppleEvents() {
nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
nsCOMPtr<nsIFile> workingDir;
nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR,
getter_AddRefs(workingDir));
if (NS_FAILED(rv)) {
// Couldn't find a working dir. Uh oh. Good job cmdline::Init can cope.
workingDir = nullptr;
}
const char* argv[3] = {nullptr, "-url", urlString};
rv = cmdLine->Init(3, argv, workingDir, nsICommandLine::STATE_REMOTE_EXPLICIT);
rv =
cmdLine->Init(3, argv, workingDir, nsICommandLine::STATE_REMOTE_EXPLICIT);
if (NS_FAILED(rv)) {
return NO;
}

Просмотреть файл

@ -26,7 +26,8 @@ void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid) {
for (int i = 1; i < aArgc; i++) {
[arguments addObject:[NSString stringWithUTF8String:aArgv[i]]];
}
NSTask* child = [NSTask launchedTaskWithLaunchPath:launchPath arguments:arguments];
NSTask* child = [NSTask launchedTaskWithLaunchPath:launchPath
arguments:arguments];
if (aPid) {
*aPid = [child processIdentifier];
// We used to use waitpid to wait for the process to terminate. This is
@ -43,31 +44,36 @@ bool InstallPrivilegedHelper() {
AuthorizationRef authRef = NULL;
OSStatus status = AuthorizationCreate(
NULL, kAuthorizationEmptyEnvironment,
kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed, &authRef);
kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed,
&authRef);
if (status != errAuthorizationSuccess) {
// AuthorizationCreate really shouldn't fail.
NSLog(@"AuthorizationCreate failed! NSOSStatusErrorDomain / %d", (int)status);
NSLog(@"AuthorizationCreate failed! NSOSStatusErrorDomain / %d",
(int)status);
return NO;
}
BOOL result = NO;
AuthorizationItem authItem = {kSMRightBlessPrivilegedHelper, 0, NULL, 0};
AuthorizationRights authRights = {1, &authItem};
AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
AuthorizationFlags flags =
kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
// Obtain the right to install our privileged helper tool.
status =
AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, flags, NULL);
status = AuthorizationCopyRights(authRef, &authRights,
kAuthorizationEmptyEnvironment, flags, NULL);
if (status != errAuthorizationSuccess) {
NSLog(@"AuthorizationCopyRights failed! NSOSStatusErrorDomain / %d", (int)status);
NSLog(@"AuthorizationCopyRights failed! NSOSStatusErrorDomain / %d",
(int)status);
} else {
CFErrorRef cfError;
// This does all the work of verifying the helper tool against the
// application and vice-versa. Once verification has passed, the embedded
// launchd.plist is extracted and placed in /Library/LaunchDaemons and then
// loaded. The executable is placed in /Library/PrivilegedHelperTools.
result = (BOOL)SMJobBless(kSMDomainSystemLaunchd, (CFStringRef) @"org.mozilla.updater", authRef,
result = (BOOL)SMJobBless(kSMDomainSystemLaunchd,
(CFStringRef) @"org.mozilla.updater", authRef,
&cfError);
if (!result) {
NSLog(@"Unable to install helper!");
@ -90,7 +96,8 @@ void AbortElevatedUpdate() {
updateServer = (id)[NSConnection
rootProxyForConnectionWithRegisteredName:@"org.mozilla.updater.server"
host:nil
usingNameServer:[NSSocketPortNameServer sharedInstance]];
usingNameServer:[NSSocketPortNameServer
sharedInstance]];
if (updateServer && [updateServer respondsToSelector:@selector(abort)]) {
[updateServer performSelector:@selector(abort)];
return;

Просмотреть файл

@ -59,30 +59,37 @@ static bool AskUserIfWeShouldLaunchExistingInstall() {
ErrorResult rv;
nsAutoCString mozTitle, mozMessage, mozLaunchExisting, mozLaunchFromDMG;
l10n->FormatValueSync("prompt-to-launch-existing-app-title"_ns, {}, mozTitle, rv);
l10n->FormatValueSync("prompt-to-launch-existing-app-title"_ns, {}, mozTitle,
rv);
if (rv.Failed()) {
return false;
}
l10n->FormatValueSync("prompt-to-launch-existing-app-message"_ns, {}, mozMessage, rv);
l10n->FormatValueSync("prompt-to-launch-existing-app-message"_ns, {},
mozMessage, rv);
if (rv.Failed()) {
return false;
}
l10n->FormatValueSync("prompt-to-launch-existing-app-yes-button"_ns, {}, mozLaunchExisting, rv);
l10n->FormatValueSync("prompt-to-launch-existing-app-yes-button"_ns, {},
mozLaunchExisting, rv);
if (rv.Failed()) {
return false;
}
l10n->FormatValueSync("prompt-to-launch-existing-app-no-button"_ns, {}, mozLaunchFromDMG, rv);
l10n->FormatValueSync("prompt-to-launch-existing-app-no-button"_ns, {},
mozLaunchFromDMG, rv);
if (rv.Failed()) {
return false;
}
NSString* title = [NSString stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSString* title = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSString* launchExisting =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozLaunchExisting.get())];
[NSString stringWithUTF8String:reinterpret_cast<const char*>(
mozLaunchExisting.get())];
NSString* launchFromDMG =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozLaunchFromDMG.get())];
[NSString stringWithUTF8String:reinterpret_cast<const char*>(
mozLaunchFromDMG.get())];
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
@ -144,18 +151,20 @@ static bool AskUserIfWeShouldInstall() {
if (rv.Failed()) {
return false;
}
l10n->FormatValueSync("prompt-to-install-no-button"_ns, {}, mozDontInstall, rv);
l10n->FormatValueSync("prompt-to-install-no-button"_ns, {}, mozDontInstall,
rv);
if (rv.Failed()) {
return false;
}
NSString* title = [NSString stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSString* install =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozInstall.get())];
NSString* dontInstall =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozDontInstall.get())];
NSString* title = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSString* install = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozInstall.get())];
NSString* dontInstall = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozDontInstall.get())];
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
@ -179,15 +188,15 @@ static bool AskUserIfWeShouldInstall() {
// AskUserIfWeShouldInstall
// |
// | ---> [NSApp run]
// | |
// | | -----> task
// | | | -----------> [alert runModal]
// | | | | (User selects button)
// | | | <--------------- done
// | | |
// | | | -----------> [NSApp stop:nil]
// | | | <-----------
// | | <--------
// | |
// | | ---> task
// | | | ----> [alert runModal]
// | | | | (User selects button)
// | | | <--------- done
// | | |
// | | | -----> [NSApp stop:nil]
// | | | <-----
// | | <-----
// | <-------
// done
__block NSInteger result = -1;
@ -225,9 +234,10 @@ static void ShowInstallFailedDialog() {
return;
}
NSString* title = [NSString stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message =
[NSString stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSString* title = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozTitle.get())];
NSString* message = [NSString
stringWithUTF8String:reinterpret_cast<const char*>(mozMessage.get())];
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
@ -322,8 +332,9 @@ static bool InstallFromPath(NSString* aBundlePath, NSString* aDestPath) {
NSString* destDir = [aDestPath stringByDeletingLastPathComponent];
if (!installSuccessful && ![fileManager isWritableFileAtPath:destDir]) {
NSString* updaterBinPath = [NSString pathWithComponents:@[
aBundlePath, @"Contents", @"MacOS", [NSString stringWithUTF8String:UPDATER_APP], @"Contents",
@"MacOS", [NSString stringWithUTF8String:UPDATER_BIN]
aBundlePath, @"Contents", @"MacOS",
[NSString stringWithUTF8String:UPDATER_APP], @"Contents", @"MacOS",
[NSString stringWithUTF8String:UPDATER_BIN]
]];
NSArray* arguments = @[ @"-dmgInstall", aBundlePath, aDestPath ];
@ -354,7 +365,8 @@ static bool InstallFromPath(NSString* aBundlePath, NSString* aDestPath) {
bool IsAppRunningFromDmg() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
const char* path = [[[NSBundle mainBundle] bundlePath] fileSystemRepresentation];
const char* path =
[[[NSBundle mainBundle] bundlePath] fileSystemRepresentation];
struct statfs statfsBuf;
if (statfs(path, &statfsBuf) != 0) {
@ -388,11 +400,13 @@ bool IsAppRunningFromDmg() {
// Get the IOMedia object:
// (Note: IOServiceGetMatchingServices takes ownership of serviceDict's ref.)
CFMutableDictionaryRef serviceDict = IOBSDNameMatching(kIOMasterPortDefault, 0, bsdDeviceName);
CFMutableDictionaryRef serviceDict =
IOBSDNameMatching(kIOMasterPortDefault, 0, bsdDeviceName);
if (!serviceDict) {
return false;
}
io_service_t media = IOServiceGetMatchingService(kIOMasterPortDefault, serviceDict);
io_service_t media =
IOServiceGetMatchingService(kIOMasterPortDefault, serviceDict);
if (!media || !IOObjectConformsTo(media, "IOMedia")) {
return false;
}
@ -401,14 +415,16 @@ bool IsAppRunningFromDmg() {
// (taking care to start with `media` itself):
io_service_t imageDrive = IO_OBJECT_NULL;
io_iterator_t iter;
if (IORegistryEntryCreateIterator(media, kIOServicePlane,
kIORegistryIterateRecursively | kIORegistryIterateParents,
&iter) != KERN_SUCCESS) {
if (IORegistryEntryCreateIterator(
media, kIOServicePlane,
kIORegistryIterateRecursively | kIORegistryIterateParents,
&iter) != KERN_SUCCESS) {
IOObjectRelease(media);
return false;
}
const char* imageClass =
nsCocoaFeatures::OnMontereyOrLater() ? "AppleDiskImageDevice" : "IOHDIXHDDrive";
const char* imageClass = nsCocoaFeatures::OnMontereyOrLater()
? "AppleDiskImageDevice"
: "IOHDIXHDDrive";
for (imageDrive = media; imageDrive; imageDrive = IOIteratorNext(iter)) {
if (IOObjectConformsTo(imageDrive, imageClass)) {
break;
@ -446,20 +462,22 @@ bool MaybeInstallAndRelaunch() {
// The Applications directory may not be at /Applications, although in
// practice we're unlikely to encounter since run-from-.dmg is really an
// issue with novice mac users. Still, look it up correctly:
NSArray* applicationsDirs =
NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSLocalDomainMask, YES);
NSArray* applicationsDirs = NSSearchPathForDirectoriesInDomains(
NSApplicationDirectory, NSLocalDomainMask, YES);
NSString* applicationsDir = applicationsDirs[0];
// Sanity check dir exists
NSFileManager* fileManager = [NSFileManager defaultManager];
BOOL isDir;
if (![fileManager fileExistsAtPath:applicationsDir isDirectory:&isDir] || !isDir) {
if (![fileManager fileExistsAtPath:applicationsDir isDirectory:&isDir] ||
!isDir) {
return false;
}
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
NSString* appName = [bundlePath lastPathComponent];
NSString* destPath = [applicationsDir stringByAppendingPathComponent:appName];
NSString* destPath =
[applicationsDir stringByAppendingPathComponent:appName];
// If the app (an app of the same name) is already installed we can't really
// tell without asking if we're dealing with the edge case of an

Просмотреть файл

@ -8,8 +8,10 @@
#include "UIKitDirProvider.h"
bool GetUIKitDirectory(bool aLocal, nsACString& aUserDir) {
NSSearchPathDirectory directory = aLocal ? NSCachesDirectory : NSApplicationSupportDirectory;
NSArray* paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
NSSearchPathDirectory directory =
aLocal ? NSCachesDirectory : NSApplicationSupportDirectory;
NSArray* paths =
NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
if ([paths count] == 0) {
return false;
}

Просмотреть файл

@ -21,8 +21,8 @@ static bool sBuildingCommandLine = false;
void AddToCommandLine(const char* inArgText) {
if (sArgsUsed >= sArgsAllocated - 1) {
// realloc does not free the given pointer if allocation fails
char** temp =
static_cast<char**>(realloc(sArgs, (sArgsAllocated + kArgsGrowSize) * sizeof(char*)));
char** temp = static_cast<char**>(
realloc(sArgs, (sArgsAllocated + kArgsGrowSize) * sizeof(char*)));
if (!temp) return;
sArgs = temp;
sArgsAllocated += kArgsGrowSize;
@ -67,7 +67,8 @@ void SetupMacCommandLine(int& argc, char**& argv, bool forRestart) {
// if the parent is in the foreground. This will be communicated in a
// command-line argument to the child.
if (forRestart) {
NSRunningApplication* frontApp = [[NSWorkspace sharedWorkspace] frontmostApplication];
NSRunningApplication* frontApp =
[[NSWorkspace sharedWorkspace] frontmostApplication];
if ([frontApp isEqual:[NSRunningApplication currentApplication]]) {
AddToCommandLine("-foreground");
}

Просмотреть файл

@ -119,7 +119,8 @@ nsNativeAppSupportCocoa::ReOpen() {
windowList->HasMoreElements(&more);
continue;
}
NSWindow* cocoaWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
NSWindow* cocoaWindow =
(NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
if (![cocoaWindow isMiniaturized]) {
haveNonMiniaturized = true;
break; // have un-minimized windows, nothing to do
@ -154,7 +155,8 @@ nsNativeAppSupportCocoa::ReOpen() {
nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
nsresult rv;
rv = cmdLine->Init(0, argv, nullptr, nsICommandLine::STATE_REMOTE_EXPLICIT);
rv = cmdLine->Init(0, argv, nullptr,
nsICommandLine::STATE_REMOTE_EXPLICIT);
NS_ENSURE_SUCCESS(rv, rv);
return cmdLine->Run();

Просмотреть файл

@ -13,8 +13,10 @@ bool IsRecursivelyWritable(const char* aPath) {
NSString* rootPath = [NSString stringWithUTF8String:aPath];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error = nil;
NSArray* subPaths = [fileManager subpathsOfDirectoryAtPath:rootPath error:&error];
NSMutableArray* paths = [NSMutableArray arrayWithCapacity:[subPaths count] + 1];
NSArray* subPaths = [fileManager subpathsOfDirectoryAtPath:rootPath
error:&error];
NSMutableArray* paths =
[NSMutableArray arrayWithCapacity:[subPaths count] + 1];
[paths addObject:@""];
[paths addObjectsFromArray:subPaths];
@ -26,7 +28,8 @@ bool IsRecursivelyWritable(const char* aPath) {
for (NSString* currPath in paths) {
NSString* child = [rootPath stringByAppendingPathComponent:currPath];
NSDictionary* attributes = [fileManager attributesOfItemAtPath:child error:&error];
NSDictionary* attributes = [fileManager attributesOfItemAtPath:child
error:&error];
if (error) {
[pool drain];
return false;

Просмотреть файл

@ -10,7 +10,8 @@
#include "nsILocalFileMac.h"
#include "nsIURI.h"
// We override this to make sure app bundles display their pretty name (without .app suffix)
// We override this to make sure app bundles display their pretty name (without
// .app suffix)
NS_IMETHODIMP nsLocalHandlerAppMac::GetName(nsAString& aName) {
if (mExecutable) {
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mExecutable);
@ -30,7 +31,8 @@ NS_IMETHODIMP nsLocalHandlerAppMac::GetName(nsAString& aName) {
* somewhere more central (see bug 389922).
*/
NS_IMETHODIMP
nsLocalHandlerAppMac::LaunchWithURI(nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
nsLocalHandlerAppMac::LaunchWithURI(
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult rv;
@ -45,14 +47,15 @@ nsLocalHandlerAppMac::LaunchWithURI(nsIURI* aURI, mozilla::dom::BrowsingContext*
aURI->GetAsciiSpec(uriSpec);
const UInt8* uriString = reinterpret_cast<const UInt8*>(uriSpec.get());
CFURLRef uri =
::CFURLCreateWithBytes(NULL, uriString, uriSpec.Length(), kCFStringEncodingUTF8, NULL);
CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, uriSpec.Length(),
kCFStringEncodingUTF8, NULL);
if (!uri) {
::CFRelease(appURL);
return NS_ERROR_OUT_OF_MEMORY;
}
CFArrayRef uris = ::CFArrayCreate(NULL, reinterpret_cast<const void**>(&uri), 1, NULL);
CFArrayRef uris =
::CFArrayCreate(NULL, reinterpret_cast<const void**>(&uri), 1, NULL);
if (!uris) {
::CFRelease(uri);
::CFRelease(appURL);

Просмотреть файл

@ -11,8 +11,10 @@
#include "nsMIMEInfoMac.h"
#include "nsILocalFileMac.h"
// We override this to make sure app bundles display their pretty name (without .app suffix)
NS_IMETHODIMP nsMIMEInfoMac::GetDefaultDescription(nsAString& aDefaultDescription) {
// We override this to make sure app bundles display their pretty name (without
// .app suffix)
NS_IMETHODIMP nsMIMEInfoMac::GetDefaultDescription(
nsAString& aDefaultDescription) {
nsCOMPtr<nsIFile> defaultApp = GetDefaultApplication();
if (defaultApp) {
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(defaultApp);
@ -43,7 +45,8 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile* aFile) {
if (mPreferredAction == useHelperApp) {
// we don't yet support passing content by value (rather than reference)
// to web apps. at some point, we will probably want to.
nsCOMPtr<nsILocalHandlerApp> localHandlerApp = do_QueryInterface(mPreferredApplication, &rv);
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
@ -68,7 +71,8 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile* aFile) {
tempFile->GetFSRef(&tempFileRef);
FSRef appFSRef;
if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nullptr) == noErr) {
if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef,
nullptr) == noErr) {
app = (do_CreateInstance("@mozilla.org/file/local;1"));
if (!app) return NS_ERROR_FAILURE;
app->InitWithFSRef(&appFSRef);
@ -91,8 +95,9 @@ nsresult nsMIMEInfoMac::LoadUriInternal(nsIURI* aURI) {
nsAutoCString uri;
aURI->GetSpec(uri);
if (!uri.IsEmpty()) {
CFURLRef myURLRef = ::CFURLCreateWithBytes(kCFAllocatorDefault, (const UInt8*)uri.get(),
strlen(uri.get()), kCFStringEncodingUTF8, NULL);
CFURLRef myURLRef =
::CFURLCreateWithBytes(kCFAllocatorDefault, (const UInt8*)uri.get(),
strlen(uri.get()), kCFStringEncodingUTF8, NULL);
if (myURLRef) {
OSStatus status = ::LSOpenCFURLRef(myURLRef, NULL);
if (status == noErr) rv = NS_OK;

Просмотреть файл

@ -25,7 +25,8 @@
#import <ApplicationServices/ApplicationServices.h>
// chrome URL's
#define HELPERAPPLAUNCHER_BUNDLE_URL "chrome://global/locale/helperAppLauncher.properties"
#define HELPERAPPLAUNCHER_BUNDLE_URL \
"chrome://global/locale/helperAppLauncher.properties"
#define BRAND_BUNDLE_URL "chrome://branding/locale/brand.properties"
nsresult GetDefaultBundleURL(const nsACString& aScheme, CFURLRef* aBundleURL) {
@ -34,18 +35,20 @@ nsresult GetDefaultBundleURL(const nsACString& aScheme, CFURLRef* aBundleURL) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
CFStringRef schemeCFString = ::CFStringCreateWithBytes(
kCFAllocatorDefault, (const UInt8*)PromiseFlatCString(aScheme).get(), aScheme.Length(),
kCFStringEncodingUTF8, false);
kCFAllocatorDefault, (const UInt8*)PromiseFlatCString(aScheme).get(),
aScheme.Length(), kCFStringEncodingUTF8, false);
if (schemeCFString) {
CFStringRef lookupCFString =
::CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:"), schemeCFString);
if (lookupCFString) {
CFURLRef lookupCFURL = ::CFURLCreateWithString(NULL, lookupCFString, NULL);
CFURLRef lookupCFURL =
::CFURLCreateWithString(NULL, lookupCFString, NULL);
if (lookupCFURL) {
*aBundleURL = ::LSCopyDefaultApplicationURLForURL(lookupCFURL, kLSRolesAll, NULL);
*aBundleURL =
::LSCopyDefaultApplicationURLForURL(lookupCFURL, kLSRolesAll, NULL);
if (*aBundleURL) {
rv = NS_OK;
}
@ -88,15 +91,15 @@ using mozilla::LogLevel;
nsOSHelperAppService::~nsOSHelperAppService() {}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char* aProtocolScheme,
bool* aHandlerExists) {
nsresult nsOSHelperAppService::OSProtocolHandlerExists(
const char* aProtocolScheme, bool* aHandlerExists) {
// CFStringCreateWithBytes() can fail even if we're not out of memory --
// for example if the 'bytes' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
CFStringRef schemeString =
::CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)aProtocolScheme,
strlen(aProtocolScheme), kCFStringEncodingUTF8, false);
CFStringRef schemeString = ::CFStringCreateWithBytes(
kCFAllocatorDefault, (const UInt8*)aProtocolScheme,
strlen(aProtocolScheme), kCFStringEncodingUTF8, false);
if (schemeString) {
// LSCopyDefaultHandlerForURLScheme() can fail to find the default handler
// for aProtocolScheme when it's never been explicitly set (using
@ -118,8 +121,8 @@ nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char* aProtocolSche
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme,
nsAString& _retval) {
NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(
const nsACString& aScheme, nsAString& _retval) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult rv = NS_ERROR_NOT_AVAILABLE;
@ -136,14 +139,17 @@ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString&
// Get the human-readable name of the bundle
CFStringRef bundleName =
(CFStringRef)::CFBundleGetValueForInfoDictionaryKey(handlerBundle, kCFBundleNameKey);
(CFStringRef)::CFBundleGetValueForInfoDictionaryKey(handlerBundle,
kCFBundleNameKey);
if (bundleName) {
AutoTArray<UniChar, 255> buffer;
CFIndex bundleNameLength = ::CFStringGetLength(bundleName);
buffer.SetLength(bundleNameLength);
::CFStringGetCharacters(bundleName, CFRangeMake(0, bundleNameLength), buffer.Elements());
_retval.Assign(reinterpret_cast<char16_t*>(buffer.Elements()), bundleNameLength);
::CFStringGetCharacters(bundleName, CFRangeMake(0, bundleNameLength),
buffer.Elements());
_retval.Assign(reinterpret_cast<char16_t*>(buffer.Elements()),
bundleNameLength);
rv = NS_OK;
}
::CFRelease(handlerBundle);
@ -155,8 +161,8 @@ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString&
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(const nsACString& aScheme,
bool* _retval) {
NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(
const nsACString& aScheme, bool* _retval) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult rv = NS_ERROR_NOT_AVAILABLE;
@ -164,7 +170,8 @@ NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(const nsACS
CFURLRef handlerBundleURL;
rv = GetDefaultBundleURL(aScheme, &handlerBundleURL);
if (NS_SUCCEEDED(rv) && handlerBundleURL) {
// Ensure we don't accidentally return success if we can't get an app bundle.
// Ensure we don't accidentally return success if we can't get an app
// bundle.
rv = NS_ERROR_NOT_AVAILABLE;
CFBundleRef appBundle = ::CFBundleGetMainBundle();
if (appBundle) {
@ -181,23 +188,25 @@ NS_IMETHODIMP nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(const nsACS
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
nsresult nsOSHelperAppService::GetFileTokenForPath(const char16_t* aPlatformAppPath,
nsIFile** aFile) {
nsresult nsOSHelperAppService::GetFileTokenForPath(
const char16_t* aPlatformAppPath, nsIFile** aFile) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsresult rv;
nsCOMPtr<nsILocalFileMac> localFile(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
nsCOMPtr<nsILocalFileMac> localFile(
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
CFURLRef pathAsCFURL;
CFStringRef pathAsCFString = ::CFStringCreateWithCharacters(
NULL, reinterpret_cast<const UniChar*>(aPlatformAppPath), NS_strlen(aPlatformAppPath));
NULL, reinterpret_cast<const UniChar*>(aPlatformAppPath),
NS_strlen(aPlatformAppPath));
if (!pathAsCFString) return NS_ERROR_OUT_OF_MEMORY;
if (::CFStringGetCharacterAtIndex(pathAsCFString, 0) == '/') {
// we have a Posix path
pathAsCFURL =
::CFURLCreateWithFileSystemPath(nullptr, pathAsCFString, kCFURLPOSIXPathStyle, false);
pathAsCFURL = ::CFURLCreateWithFileSystemPath(nullptr, pathAsCFString,
kCFURLPOSIXPathStyle, false);
if (!pathAsCFURL) {
::CFRelease(pathAsCFString);
return NS_ERROR_OUT_OF_MEMORY;
@ -214,8 +223,8 @@ nsresult nsOSHelperAppService::GetFileTokenForPath(const char16_t* aPlatformAppP
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
pathAsCFURL =
::CFURLCreateWithFileSystemPath(nullptr, pathAsCFString, kCFURLHFSPathStyle, false);
pathAsCFURL = ::CFURLCreateWithFileSystemPath(nullptr, pathAsCFString,
kCFURLHFSPathStyle, false);
if (!pathAsCFURL) {
::CFRelease(pathAsCFString);
return NS_ERROR_OUT_OF_MEMORY;
@ -259,7 +268,8 @@ static CFArrayRef GetMIMETypesHandledByApp(FSRef* aAppRef) {
if (!infoDict) {
return NULL;
}
CFTypeRef cfObject = ::CFDictionaryGetValue(infoDict, CFSTR("CFBundleDocumentTypes"));
CFTypeRef cfObject =
::CFDictionaryGetValue(infoDict, CFSTR("CFBundleDocumentTypes"));
if (!cfObject || (::CFGetTypeID(cfObject) != ::CFArrayGetTypeID())) {
::CFRelease(infoDict);
return NULL;
@ -307,7 +317,8 @@ static CFArrayRef GetMIMETypesHandledByApp(FSRef* aAppRef) {
}
nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
const nsACString& aFileExt,
bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_ASSERT(XRE_IsParentProcess());
@ -318,7 +329,8 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsCString& flatExt = PromiseFlatCString(aFileExt);
MOZ_LOG(sLog, LogLevel::Debug,
("Mac: HelperAppService lookup for type '%s' ext '%s'\n", flatType.get(), flatExt.get()));
("Mac: HelperAppService lookup for type '%s' ext '%s'\n",
flatType.get(), flatExt.get()));
// Create a Mac-specific MIME info so we can use Mac-specific members.
RefPtr<nsMIMEInfoMac> mimeInfoMac = new nsMIMEInfoMac(aMIMEType);
@ -337,13 +349,15 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
CFStringRef cfMIMEType = NULL;
if (!aMIMEType.IsEmpty()) {
typeIsOctetStream = aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM);
typeIsOctetStream =
aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM);
CFURLRef appURL = NULL;
// CFStringCreateWithCString() can fail even if we're not out of memory --
// for example if the 'cStr' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
cfMIMEType = ::CFStringCreateWithCString(NULL, flatType.get(), kCFStringEncodingUTF8);
cfMIMEType = ::CFStringCreateWithCString(NULL, flatType.get(),
kCFStringEncodingUTF8);
if (cfMIMEType) {
err = ::LSCopyApplicationForMIMEType(cfMIMEType, kLSRolesAll, &appURL);
if ((err == noErr) && appURL && ::CFURLGetFSRef(appURL, &typeAppFSRef)) {
@ -361,13 +375,15 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
// for example if the 'cStr' parameter is something very weird (like
// "\xFF\xFF~"), or possibly if it can't be interpreted as using what's
// specified in the 'encoding' parameter. See bug 548719.
CFStringRef cfExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
CFStringRef cfExt =
::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
if (cfExt) {
err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, cfExt, kLSRolesAll,
&extAppFSRef, nullptr);
err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, cfExt,
kLSRolesAll, &extAppFSRef, nullptr);
if (err == noErr) {
haveAppForExt = true;
MOZ_LOG(sLog, LogLevel::Debug, ("LSGetApplicationForInfo found a default application\n"));
MOZ_LOG(sLog, LogLevel::Debug,
("LSGetApplicationForInfo found a default application\n"));
}
::CFRelease(cfExt);
}
@ -375,7 +391,8 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
if (haveAppForType && haveAppForExt) {
// Do aMIMEType and aFileExt match?
if (::FSCompareFSRefs((const FSRef*)&typeAppFSRef, (const FSRef*)&extAppFSRef) == noErr) {
if (::FSCompareFSRefs((const FSRef*)&typeAppFSRef,
(const FSRef*)&extAppFSRef) == noErr) {
typeAppIsDefault = true;
*aFound = true;
}
@ -418,9 +435,10 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
CFArrayRef extAppMIMETypes = GetMIMETypesHandledByApp(&extAppFSRef);
if (extAppMIMETypes) {
if (cfMIMEType) {
if (::CFArrayContainsValue(extAppMIMETypes,
::CFRangeMake(0, ::CFArrayGetCount(extAppMIMETypes)),
cfMIMEType)) {
if (::CFArrayContainsValue(
extAppMIMETypes,
::CFRangeMake(0, ::CFArrayGetCount(extAppMIMETypes)),
cfMIMEType)) {
extAppIsDefault = true;
*aFound = true;
}
@ -445,11 +463,13 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
// the doc for this method says that if we have a MIME type (in
// aMIMEType), we need to give it preference.)
NSURLFileTypeMappings* map = [NSURLFileTypeMappings sharedMappings];
NSString* extStr = [NSString stringWithCString:flatExt.get() encoding:NSASCIIStringEncoding];
NSString* extStr = [NSString stringWithCString:flatExt.get()
encoding:NSASCIIStringEncoding];
NSString* typeStr = map ? [map MIMETypeForExtension:extStr] : NULL;
if (typeStr) {
nsAutoCString mimeType;
mimeType.Assign((char*)[typeStr cStringUsingEncoding:NSASCIIStringEncoding]);
mimeType.Assign(
(char*)[typeStr cStringUsingEncoding:NSASCIIStringEncoding]);
mimeInfoMac->SetMIMEType(mimeType);
haveAppForType = true;
} else {
@ -476,7 +496,8 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
if (haveAppForExt) mimeInfoMac->AppendExtension(aFileExt);
nsresult rv;
nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
nsCOMPtr<nsILocalFileMac> app(
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
if (NS_FAILED(rv)) {
[localPool release];
return rv;
@ -485,20 +506,22 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
CFStringRef cfAppName = NULL;
if (typeAppIsDefault) {
app->InitWithFSRef(&typeAppFSRef);
::LSCopyItemAttribute((const FSRef*)&typeAppFSRef, kLSRolesAll, kLSItemDisplayName,
(CFTypeRef*)&cfAppName);
::LSCopyItemAttribute((const FSRef*)&typeAppFSRef, kLSRolesAll,
kLSItemDisplayName, (CFTypeRef*)&cfAppName);
} else {
app->InitWithFSRef(&extAppFSRef);
::LSCopyItemAttribute((const FSRef*)&extAppFSRef, kLSRolesAll, kLSItemDisplayName,
(CFTypeRef*)&cfAppName);
::LSCopyItemAttribute((const FSRef*)&extAppFSRef, kLSRolesAll,
kLSItemDisplayName, (CFTypeRef*)&cfAppName);
}
if (cfAppName) {
AutoTArray<UniChar, 255> buffer;
CFIndex appNameLength = ::CFStringGetLength(cfAppName);
buffer.SetLength(appNameLength);
::CFStringGetCharacters(cfAppName, CFRangeMake(0, appNameLength), buffer.Elements());
::CFStringGetCharacters(cfAppName, CFRangeMake(0, appNameLength),
buffer.Elements());
nsAutoString appName;
appName.Assign(reinterpret_cast<char16_t*>(buffer.Elements()), appNameLength);
appName.Assign(reinterpret_cast<char16_t*>(buffer.Elements()),
appNameLength);
mimeInfoMac->SetDefaultDescription(appName);
::CFRelease(cfAppName);
}
@ -516,25 +539,29 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
// If we have a MIME type, make sure its extension list is included in our
// list.
NSURLFileTypeMappings* map = [NSURLFileTypeMappings sharedMappings];
NSString* typeStr = [NSString stringWithCString:mimeType.get() encoding:NSASCIIStringEncoding];
NSString* typeStr = [NSString stringWithCString:mimeType.get()
encoding:NSASCIIStringEncoding];
NSArray* extensionsList = map ? [map extensionsForMIMEType:typeStr] : NULL;
if (extensionsList) {
for (NSString* extension in extensionsList) {
nsAutoCString ext;
ext.Assign((char*)[extension cStringUsingEncoding:NSASCIIStringEncoding]);
ext.Assign(
(char*)[extension cStringUsingEncoding:NSASCIIStringEncoding]);
mimeInfoMac->AppendExtension(ext);
}
}
if (CFStringRef cfType =
::CFStringCreateWithCString(NULL, mimeType.get(), kCFStringEncodingUTF8)) {
if (CFStringRef cfType = ::CFStringCreateWithCString(
NULL, mimeType.get(), kCFStringEncodingUTF8)) {
if (CFStringRef cfTypeDesc = ::UTTypeCopyDescription(cfType)) {
AutoTArray<UniChar, 255> buffer;
CFIndex typeDescLength = ::CFStringGetLength(cfTypeDesc);
buffer.SetLength(typeDescLength);
::CFStringGetCharacters(cfTypeDesc, CFRangeMake(0, typeDescLength), buffer.Elements());
::CFStringGetCharacters(cfTypeDesc, CFRangeMake(0, typeDescLength),
buffer.Elements());
nsAutoString typeDesc;
typeDesc.Assign(reinterpret_cast<char16_t*>(buffer.Elements()), typeDescLength);
typeDesc.Assign(reinterpret_cast<char16_t*>(buffer.Elements()),
typeDescLength);
mimeInfoMac->SetDescription(typeDesc);
::CFRelease(cfTypeDesc);
}
@ -542,7 +569,8 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
}
}
MOZ_LOG(sLog, LogLevel::Debug, ("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound));
MOZ_LOG(sLog, LogLevel::Debug,
("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound));
[localPool release];
mimeInfoMac.forget(aMIMEInfo);
@ -552,14 +580,17 @@ nsresult nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
}
NS_IMETHODIMP
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString& aScheme, bool* found,
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval) {
NS_ASSERTION(!aScheme.IsEmpty(), "No scheme was specified!");
nsresult rv = OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(), found);
nsresult rv =
OSProtocolHandlerExists(nsPromiseFlatCString(aScheme).get(), found);
if (NS_FAILED(rv)) return rv;
nsMIMEInfoMac* handlerInfo = new nsMIMEInfoMac(aScheme, nsMIMEInfoBase::eProtocolInfo);
nsMIMEInfoMac* handlerInfo =
new nsMIMEInfoMac(aScheme, nsMIMEInfoBase::eProtocolInfo);
NS_ENSURE_TRUE(handlerInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*_retval = handlerInfo);

Просмотреть файл

@ -10,7 +10,7 @@
#include "nsIURI.h"
NS_IMETHODIMP
nsLocalHandlerAppUIKit::LaunchWithURI(nsIURI* aURI,
mozilla::dom::BrowsingContext* aBrowsingContext) {
nsLocalHandlerAppUIKit::LaunchWithURI(
nsIURI* aURI, mozilla::dom::BrowsingContext* aBrowsingContext) {
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -7,6 +7,10 @@
#include "nsMIMEInfoUIKit.h"
NS_IMETHODIMP
nsMIMEInfoUIKit::LaunchWithFile(nsIFile* aFile) { return NS_ERROR_NOT_IMPLEMENTED; }
nsMIMEInfoUIKit::LaunchWithFile(nsIFile* aFile) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult nsMIMEInfoUIKit::LoadUriInternal(nsIURI* aURI) { return NS_ERROR_NOT_IMPLEMENTED; }
nsresult nsMIMEInfoUIKit::LoadUriInternal(nsIURI* aURI) {
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -10,43 +10,48 @@ nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService() {}
nsOSHelperAppService::~nsOSHelperAppService() {}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char* aProtocolScheme,
bool* aHandlerExists) {
nsresult nsOSHelperAppService::OSProtocolHandlerExists(
const char* aProtocolScheme, bool* aHandlerExists) {
*aHandlerExists = false;
return NS_OK;
}
NS_IMETHODIMP
nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval) {
nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme,
nsAString& _retval) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(const nsACString& aScheme, bool* _retval) {
nsOSHelperAppService::IsCurrentAppOSDefaultForProtocol(
const nsACString& aScheme, bool* _retval) {
return NS_ERROR_NOT_AVAILABLE;
}
nsresult nsOSHelperAppService::GetFileTokenForPath(const char16_t* aPlatformAppPath,
nsIFile** aFile) {
nsresult nsOSHelperAppService::GetFileTokenForPath(
const char16_t* aPlatformAppPath, nsIFile** aFile) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt,
nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType,
const nsACString& aFileExt,
nsIMIMEInfo** aMIMEInfo) {
return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt,
aMIMEInfo);
}
NS_IMETHODIMP nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
NS_IMETHODIMP nsOSHelperAppService::GetMIMEInfoFromOS(
const nsACString& aMIMEType, const nsACString& aFileExt, bool* aFound,
nsIMIMEInfo** aMIMEInfo) {
*aMIMEInfo = nullptr;
*aFound = false;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString& aScheme, bool* found,
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString& aScheme,
bool* found,
nsIHandlerInfo** _retval) {
*found = false;
return NS_OK;

Просмотреть файл

@ -29,7 +29,8 @@ static void ToolbarThemePrefChanged(const char* aPref, void* aUserInfo);
if (XRE_IsParentProcess()) {
mozilla::Preferences::RegisterCallbackAndCall(
&ToolbarThemePrefChanged,
nsDependentCString(mozilla::StaticPrefs::GetPrefName_browser_theme_toolbar_theme()));
nsDependentCString(
mozilla::StaticPrefs::GetPrefName_browser_theme_toolbar_theme()));
}
}
return sInstance;
@ -60,9 +61,10 @@ static void ToolbarThemePrefChanged(const char* aPref, void* aUserInfo);
}
+ (NSSet*)keyPathsForValuesAffectingEffectiveAppearance {
// Automatically notify any key-value observers of our effectiveAppearance property whenever the
// pref or the NSApp's effectiveAppearance change.
return [NSSet setWithObjects:@"toolbarTheme", @"_app.effectiveAppearance", nil];
// Automatically notify any key-value observers of our effectiveAppearance
// property whenever the pref or the NSApp's effectiveAppearance change.
return
[NSSet setWithObjects:@"toolbarTheme", @"_app.effectiveAppearance", nil];
}
- (NSAppearance*)effectiveAppearance {

Просмотреть файл

@ -52,15 +52,16 @@ void SetDesktopImage(nsIFile* aImage) {
}
// Use existing options for this screen
NSDictionary* screenOptions =
[[NSWorkspace sharedWorkspace] desktopImageOptionsForScreen:currentScreen];
NSDictionary* screenOptions = [[NSWorkspace sharedWorkspace]
desktopImageOptionsForScreen:currentScreen];
NSError* error = nil;
if (![[NSWorkspace sharedWorkspace] setDesktopImageURL:url
forScreen:currentScreen
options:screenOptions
error:&error]) {
LOG("%s ERROR: setDesktopImageURL failed (%ld)", __func__, (long)[error code]);
LOG("%s ERROR: setDesktopImageURL failed (%ld)", __func__,
(long)[error code]);
}
}

Просмотреть файл

@ -31,7 +31,9 @@ using namespace mozilla::widget;
NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
#endif
GfxInfo::GfxInfo() : mNumGPUsDetected(0), mOSXVersion{0} { mAdapterRAM[0] = mAdapterRAM[1] = 0; }
GfxInfo::GfxInfo() : mNumGPUsDetected(0), mOSXVersion{0} {
mAdapterRAM[0] = mAdapterRAM[1] = 0;
}
static OperatingSystem OSXVersionToOperatingSystem(uint32_t aOSXVersion) {
switch (nsCocoaFeatures::ExtractMajorVersion(aOSXVersion)) {
@ -78,10 +80,11 @@ static OperatingSystem OSXVersionToOperatingSystem(uint32_t aOSXVersion) {
return OperatingSystem::Unknown;
}
// The following three functions are derived from Chromium code
static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, CFStringRef propertyName) {
return IORegistryEntrySearchCFProperty(dspPort, kIOServicePlane, propertyName,
kCFAllocatorDefault,
kIORegistryIterateRecursively | kIORegistryIterateParents);
static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
CFStringRef propertyName) {
return IORegistryEntrySearchCFProperty(
dspPort, kIOServicePlane, propertyName, kCFAllocatorDefault,
kIORegistryIterateRecursively | kIORegistryIterateParents);
}
static uint32_t IntValueOfCFData(CFDataRef d) {
@ -100,29 +103,33 @@ void GfxInfo::GetDeviceInfo() {
CFMutableDictionaryRef pci_dev_dict = IOServiceMatching("IOPCIDevice");
io_iterator_t io_iter;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, pci_dev_dict, &io_iter) !=
kIOReturnSuccess) {
MOZ_DIAGNOSTIC_ASSERT(false,
"Failed to detect any GPUs (couldn't enumerate IOPCIDevice services)");
if (IOServiceGetMatchingServices(kIOMasterPortDefault, pci_dev_dict,
&io_iter) != kIOReturnSuccess) {
MOZ_DIAGNOSTIC_ASSERT(
false,
"Failed to detect any GPUs (couldn't enumerate IOPCIDevice services)");
return;
}
io_registry_entry_t entry = IO_OBJECT_NULL;
while ((entry = IOIteratorNext(io_iter)) != IO_OBJECT_NULL) {
constexpr uint32_t kClassCodeDisplayVGA = 0x30000;
CFTypeRef class_code_ref = SearchPortForProperty(entry, CFSTR("class-code"));
CFTypeRef class_code_ref =
SearchPortForProperty(entry, CFSTR("class-code"));
if (class_code_ref) {
const uint32_t class_code = IntValueOfCFData((CFDataRef)class_code_ref);
CFRelease(class_code_ref);
if (class_code == kClassCodeDisplayVGA) {
CFTypeRef vendor_id_ref = SearchPortForProperty(entry, CFSTR("vendor-id"));
CFTypeRef vendor_id_ref =
SearchPortForProperty(entry, CFSTR("vendor-id"));
if (vendor_id_ref) {
mAdapterVendorID[mNumGPUsDetected].AppendPrintf(
"0x%04x", IntValueOfCFData((CFDataRef)vendor_id_ref));
CFRelease(vendor_id_ref);
}
CFTypeRef device_id_ref = SearchPortForProperty(entry, CFSTR("device-id"));
CFTypeRef device_id_ref =
SearchPortForProperty(entry, CFSTR("device-id"));
if (device_id_ref) {
mAdapterDeviceID[mNumGPUsDetected].AppendPrintf(
"0x%04x", IntValueOfCFData((CFDataRef)device_id_ref));
@ -145,14 +152,15 @@ void GfxInfo::GetDeviceInfo() {
}
CFMutableDictionaryRef agx_dev_dict = IOServiceMatching("AGXAccelerator");
if (IOServiceGetMatchingServices(kIOMasterPortDefault, agx_dev_dict, &io_iter) ==
kIOReturnSuccess) {
if (IOServiceGetMatchingServices(kIOMasterPortDefault, agx_dev_dict,
&io_iter) == kIOReturnSuccess) {
io_registry_entry_t entry = IO_OBJECT_NULL;
while ((entry = IOIteratorNext(io_iter)) != IO_OBJECT_NULL) {
CFTypeRef vendor_id_ref = SearchPortForProperty(entry, CFSTR("vendor-id"));
CFTypeRef vendor_id_ref =
SearchPortForProperty(entry, CFSTR("vendor-id"));
if (vendor_id_ref) {
mAdapterVendorID[mNumGPUsDetected].AppendPrintf("0x%04x",
IntValueOfCFData((CFDataRef)vendor_id_ref));
mAdapterVendorID[mNumGPUsDetected].AppendPrintf(
"0x%04x", IntValueOfCFData((CFDataRef)vendor_id_ref));
CFRelease(vendor_id_ref);
++mNumGPUsDetected;
}
@ -189,22 +197,32 @@ NS_IMETHODIMP
GfxInfo::GetDWriteEnabled(bool* aEnabled) { return NS_ERROR_FAILURE; }
/* readonly attribute bool HasBattery; */
NS_IMETHODIMP GfxInfo::GetHasBattery(bool* aHasBattery) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHODIMP GfxInfo::GetHasBattery(bool* aHasBattery) {
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute DOMString DWriteVersion; */
NS_IMETHODIMP
GfxInfo::GetDWriteVersion(nsAString& aDwriteVersion) { return NS_ERROR_FAILURE; }
GfxInfo::GetDWriteVersion(nsAString& aDwriteVersion) {
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality) { return NS_ERROR_FAILURE; }
GfxInfo::GetEmbeddedInFirefoxReality(bool* aEmbeddedInFirefoxReality) {
return NS_ERROR_FAILURE;
}
/* readonly attribute DOMString cleartypeParameters; */
NS_IMETHODIMP
GfxInfo::GetCleartypeParameters(nsAString& aCleartypeParams) { return NS_ERROR_FAILURE; }
GfxInfo::GetCleartypeParameters(nsAString& aCleartypeParams) {
return NS_ERROR_FAILURE;
}
/* readonly attribute DOMString windowProtocol; */
NS_IMETHODIMP
GfxInfo::GetWindowProtocol(nsAString& aWindowProtocol) { return NS_ERROR_NOT_IMPLEMENTED; }
GfxInfo::GetWindowProtocol(nsAString& aWindowProtocol) {
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute DOMString testType; */
NS_IMETHODIMP
@ -348,14 +366,20 @@ GfxInfo::GetAdapterDeviceID2(nsAString& aAdapterDeviceID) {
/* readonly attribute DOMString adapterSubsysID; */
NS_IMETHODIMP
GfxInfo::GetAdapterSubsysID(nsAString& aAdapterSubsysID) { return NS_ERROR_FAILURE; }
GfxInfo::GetAdapterSubsysID(nsAString& aAdapterSubsysID) {
return NS_ERROR_FAILURE;
}
/* readonly attribute DOMString adapterSubsysID2; */
NS_IMETHODIMP
GfxInfo::GetAdapterSubsysID2(nsAString& aAdapterSubsysID) { return NS_ERROR_FAILURE; }
GfxInfo::GetAdapterSubsysID2(nsAString& aAdapterSubsysID) {
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GfxInfo::GetDrmRenderDevice(nsACString& aDrmRenderDevice) { return NS_ERROR_NOT_IMPLEMENTED; }
GfxInfo::GetDrmRenderDevice(nsACString& aDrmRenderDevice) {
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute boolean isGPU2Active; */
NS_IMETHODIMP
@ -372,60 +396,70 @@ void GfxInfo::AddCrashReportAnnotations() {
GetAdapterDriverVersion(driverVersion);
CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID, narrowVendorID);
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID, narrowDeviceID);
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDriverVersion,
narrowDriverVersion);
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
narrowVendorID);
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
narrowDeviceID);
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
}
// We don't support checking driver versions on Mac.
#define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, device, features, blockOn, ruleId) \
APPEND_TO_DRIVER_BLOCKLIST(os, device, features, blockOn, DRIVER_COMPARISON_IGNORED, \
V(0, 0, 0, 0), ruleId, "")
#define IMPLEMENT_MAC_DRIVER_BLOCKLIST(os, device, features, blockOn, ruleId) \
APPEND_TO_DRIVER_BLOCKLIST(os, device, features, blockOn, \
DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0), ruleId, \
"")
const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
if (!sDriverInfo->Length()) {
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::RadeonX1000, nsIGfxInfo::FEATURE_OPENGL_LAYERS,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, "FEATURE_FAILURE_MAC_RADEONX1000_NO_TEXTURE2D");
OperatingSystem::OSX, DeviceFamily::RadeonX1000,
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_RADEONX1000_NO_TEXTURE2D");
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::Geforce7300GT, nsIGfxInfo::FEATURE_WEBGL_OPENGL,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, "FEATURE_FAILURE_MAC_7300_NO_WEBGL");
IMPLEMENT_MAC_DRIVER_BLOCKLIST(OperatingSystem::OSX, DeviceFamily::IntelHDGraphicsToIvyBridge,
nsIGfxInfo::FEATURE_GL_SWIZZLE,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_INTELHD4000_NO_SWIZZLE");
// We block texture swizzling everwhere on mac because it's broken in some configurations
// and we want to support GPU switching.
OperatingSystem::OSX, DeviceFamily::Geforce7300GT,
nsIGfxInfo::FEATURE_WEBGL_OPENGL, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_7300_NO_WEBGL");
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::IntelHDGraphicsToIvyBridge,
nsIGfxInfo::FEATURE_GL_SWIZZLE, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_INTELHD4000_NO_SWIZZLE");
// We block texture swizzling everwhere on mac because it's broken in some
// configurations and we want to support GPU switching.
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::All, nsIGfxInfo::FEATURE_GL_SWIZZLE,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, "FEATURE_FAILURE_MAC_GPU_SWITCHING_NO_SWIZZLE");
nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_GPU_SWITCHING_NO_SWIZZLE");
// Older generation Intel devices do not perform well with WebRender.
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::IntelWebRenderBlocked, nsIGfxInfo::FEATURE_WEBRENDER,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, "FEATURE_FAILURE_INTEL_GEN5_OR_OLDER");
OperatingSystem::OSX, DeviceFamily::IntelWebRenderBlocked,
nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_INTEL_GEN5_OR_OLDER");
// Intel HD3000 disabled due to bug 1661505
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::IntelSandyBridge, nsIGfxInfo::FEATURE_WEBRENDER,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE, "FEATURE_FAILURE_INTEL_MAC_HD3000_NO_WEBRENDER");
OperatingSystem::OSX, DeviceFamily::IntelSandyBridge,
nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_INTEL_MAC_HD3000_NO_WEBRENDER");
// wgpu doesn't safely support OOB behavior on Metal yet.
IMPLEMENT_MAC_DRIVER_BLOCKLIST(OperatingSystem::OSX, DeviceFamily::All,
nsIGfxInfo::FEATURE_WEBGPU, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_WGPU_NO_METAL_BOUNDS_CHECKS");
IMPLEMENT_MAC_DRIVER_BLOCKLIST(
OperatingSystem::OSX, DeviceFamily::All, nsIGfxInfo::FEATURE_WEBGPU,
nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
"FEATURE_FAILURE_MAC_WGPU_NO_METAL_BOUNDS_CHECKS");
}
return *sDriverInfo;
}
OperatingSystem GfxInfo::GetOperatingSystem() { return OSXVersionToOperatingSystem(mOSXVersion); }
OperatingSystem GfxInfo::GetOperatingSystem() {
return OSXVersionToOperatingSystem(mOSXVersion);
}
nsresult GfxInfo::GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus,
nsAString& aSuggestedDriverVersion,
const nsTArray<GfxDriverInfo>& aDriverInfo,
nsACString& aFailureId,
OperatingSystem* aOS /* = nullptr */) {
nsresult GfxInfo::GetFeatureStatusImpl(
int32_t aFeature, int32_t* aStatus, nsAString& aSuggestedDriverVersion,
const nsTArray<GfxDriverInfo>& aDriverInfo, nsACString& aFailureId,
OperatingSystem* aOS /* = nullptr */) {
NS_ENSURE_ARG_POINTER(aStatus);
aSuggestedDriverVersion.SetIsVoid(true);
*aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
@ -436,7 +470,8 @@ nsresult GfxInfo::GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus,
return NS_OK;
}
// Don't evaluate special cases when we're evaluating the downloaded blocklist.
// Don't evaluate special cases when we're evaluating the downloaded
// blocklist.
if (!aDriverInfo.Length()) {
if (aFeature == nsIGfxInfo::FEATURE_CANVAS2D_ACCELERATION) {
// See bug 1249659
@ -460,8 +495,8 @@ nsresult GfxInfo::GetFeatureStatusImpl(int32_t aFeature, int32_t* aStatus,
}
}
return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo,
aFailureId, &os);
return GfxInfoBase::GetFeatureStatusImpl(
aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, aFailureId, &os);
}
#ifdef DEBUG

Просмотреть файл

@ -23,19 +23,20 @@
+ (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
withSize:(NSSize)aSize
presContext:(const nsPresContext*)aPresContext
computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
computedStyle:
(const mozilla::ComputedStyle*)aComputedStyle
scaleFactor:(CGFloat)aScaleFactor {
bool isEntirelyBlack = false;
NSImage* retainedImage = nil;
nsresult rv;
if (aScaleFactor != 0.0f) {
rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, imgIContainer::FRAME_CURRENT,
aPresContext, aComputedStyle, &retainedImage,
aScaleFactor, &isEntirelyBlack);
rv = nsCocoaUtils::CreateNSImageFromImageContainer(
aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle,
&retainedImage, aScaleFactor, &isEntirelyBlack);
} else {
rv = nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle, &retainedImage,
&isEntirelyBlack);
aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle,
&retainedImage, &isEntirelyBlack);
}
NSImage* image = [retainedImage autorelease];

Просмотреть файл

@ -68,7 +68,8 @@ static BOOL sNeedToUnwindForMenuClosing = NO;
withAppearance:(NSAppearance*)aAppearance
asContextMenu:(BOOL)aIsContextMenu {
MOZ_RELEASE_ASSERT(!mPendingOpening,
"A menu is already waiting to open. Before opening the next one, either wait "
"A menu is already waiting to open. Before opening the "
"next one, either wait "
"for this one to open or cancel the request.");
NSInteger handle = ++mLastHandle;
@ -134,33 +135,36 @@ static BOOL sNeedToUnwindForMenuClosing = NO;
asContextMenu:(BOOL)aIsContextMenu {
// There are multiple ways to display an NSMenu as a context menu.
//
// 1. We can return the NSMenu from -[ChildView menuForEvent:] and the NSView will open it for
// us.
// 2. We can call +[NSMenu popUpContextMenu:withEvent:forView:] inside a mouseDown handler with a
// real mouse down event.
// 3. We can call +[NSMenu popUpContextMenu:withEvent:forView:] at a later time, with a real
// mouse event that we stored earlier.
// 4. We can call +[NSMenu popUpContextMenu:withEvent:forView:] at any time, with a synthetic
// mouse event that we create just for that purpose.
// 5. We can call -[NSMenu popUpMenuPositioningItem:atLocation:inView:] and it just takes a
// position, not an event.
// 1. We can return the NSMenu from -[ChildView menuForEvent:] and the NSView
// will open it for us.
// 2. We can call +[NSMenu popUpContextMenu:withEvent:forView:] inside a
// mouseDown handler with a real mouse down event.
// 3. We can call +[NSMenu popUpContextMenu:withEvent:forView:] at a later
// time, with a real mouse event that we stored earlier.
// 4. We can call +[NSMenu popUpContextMenu:withEvent:forView:] at any time,
// with a synthetic mouse event that we create just for that purpose.
// 5. We can call -[NSMenu popUpMenuPositioningItem:atLocation:inView:] and
// it just takes a position, not an event.
//
// 1-4 look the same, 5 looks different: 5 is made for use with NSPopUpButton, where the selected
// item needs to be shown at a specific position. If a tall menu is opened with a position close
// to the bottom edge of the screen, 5 results in a cropped menu with scroll arrows, even if the
// entire menu would fit on the screen, due to the positioning constraint.
// 1-2 only work if the menu contents are known synchronously during the call to menuForEvent or
// 1-4 look the same, 5 looks different: 5 is made for use with NSPopUpButton,
// where the selected item needs to be shown at a specific position. If a tall
// menu is opened with a position close to the bottom edge of the screen, 5
// results in a cropped menu with scroll arrows, even if the entire menu would
// fit on the screen, due to the positioning constraint. 1-2 only work if the
// menu contents are known synchronously during the call to menuForEvent or
// during the mouseDown event handler.
// NativeMenuMac::ShowAsContextMenu can be called at any time. It could be called during a
// menuForEvent call (during a "contextmenu" event handler), or during a mouseDown handler, or at
// a later time.
// The code below uses option 4 as the preferred option for context menus because it's the
// simplest: It works in all scenarios and it doesn't have the drawbacks of option 5. For popups
// that aren't context menus and that should be positioned as close as possible to the given
// screen position, we use option 5.
// NativeMenuMac::ShowAsContextMenu can be called at any time. It could be
// called during a menuForEvent call (during a "contextmenu" event handler),
// or during a mouseDown handler, or at a later time. The code below uses
// option 4 as the preferred option for context menus because it's the
// simplest: It works in all scenarios and it doesn't have the drawbacks of
// option 5. For popups that aren't context menus and that should be
// positioned as close as possible to the given screen position, we use
// option 5.
if (aAppearance) {
#if !defined(MAC_OS_VERSION_11_0) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_11_0
#if !defined(MAC_OS_VERSION_11_0) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_11_0
if (nsCocoaFeatures::OnBigSurOrLater()) {
#else
if (@available(macOS 11.0, *)) {
@ -174,18 +178,21 @@ static BOOL sNeedToUnwindForMenuClosing = NO;
if (aView) {
NSWindow* window = aView.window;
NSPoint locationInWindow = nsCocoaUtils::ConvertPointFromScreen(window, aPosition);
NSPoint locationInWindow =
nsCocoaUtils::ConvertPointFromScreen(window, aPosition);
if (aIsContextMenu) {
// Create a synthetic event at the right location and open the menu [option 4].
NSEvent* event = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown
location:locationInWindow
modifierFlags:0
timestamp:NSProcessInfo.processInfo.systemUptime
windowNumber:window.windowNumber
context:nil
eventNumber:0
clickCount:1
pressure:0.0f];
// Create a synthetic event at the right location and open the menu
// [option 4].
NSEvent* event =
[NSEvent mouseEventWithType:NSEventTypeRightMouseDown
location:locationInWindow
modifierFlags:0
timestamp:NSProcessInfo.processInfo.systemUptime
windowNumber:window.windowNumber
context:nil
eventNumber:0
clickCount:1
pressure:0.0f];
[NSMenu popUpContextMenu:aMenu withEvent:event forView:aView];
} else {
// For popups which are not context menus, we open the menu using [option
@ -193,14 +200,18 @@ static BOOL sNeedToUnwindForMenuClosing = NO;
// corner of the menu. This path is used for anchored menupopups, so we
// prefer option 5 over option 4 so that the menu doesn't get flipped if
// space is tight.
NSPoint locationInView = [aView convertPoint:locationInWindow fromView:nil];
[aMenu popUpMenuPositioningItem:nil atLocation:locationInView inView:aView];
NSPoint locationInView = [aView convertPoint:locationInWindow
fromView:nil];
[aMenu popUpMenuPositioningItem:nil
atLocation:locationInView
inView:aView];
}
} else {
// Open the menu using popUpMenuPositioningItem:atLocation:inView: [option 5].
// This is not preferred, because it positions the menu differently from how a native context
// menu would be positioned; it enforces aPosition for the top left corner even if this
// means that the menu will be displayed in a clipped fashion with scroll arrows.
// Open the menu using popUpMenuPositioningItem:atLocation:inView: [option
// 5]. This is not preferred, because it positions the menu differently from
// how a native context menu would be positioned; it enforces aPosition for
// the top left corner even if this means that the menu will be displayed in
// a clipped fashion with scroll arrows.
[aMenu popUpMenuPositioningItem:nil atLocation:aPosition inView:nil];
}
}

Просмотреть файл

@ -70,7 +70,9 @@ static MediaControlKey ToMediaControlKey(int aKeyCode) {
namespace mozilla {
namespace widget {
bool MediaHardwareKeysEventSourceMac::IsOpened() const { return mEventTap && mEventTapSource; }
bool MediaHardwareKeysEventSourceMac::IsOpened() const {
return mEventTap && mEventTapSource;
}
bool MediaHardwareKeysEventSourceMac::Open() {
LOG("Open MediaHardwareKeysEventSourceMac");
@ -89,22 +91,24 @@ bool MediaHardwareKeysEventSourceMac::StartEventTap() {
MOZ_ASSERT(!mEventTapSource);
// Add an event tap to intercept the system defined media key events.
mEventTap =
CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
CGEventMaskBit(NX_SYSDEFINED), EventTapCallback, this);
mEventTap = CGEventTapCreate(
kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
CGEventMaskBit(NX_SYSDEFINED), EventTapCallback, this);
if (!mEventTap) {
LOG("Fail to create event tap");
return false;
}
mEventTapSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mEventTap, 0);
mEventTapSource =
CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mEventTap, 0);
if (!mEventTapSource) {
LOG("Fail to create an event tap source.");
return false;
}
LOG("Add an event tap source to current loop");
CFRunLoopAddSource(CFRunLoopGetCurrent(), mEventTapSource, kCFRunLoopCommonModes);
CFRunLoopAddSource(CFRunLoopGetCurrent(), mEventTapSource,
kCFRunLoopCommonModes);
return true;
}
@ -115,18 +119,20 @@ void MediaHardwareKeysEventSourceMac::StopEventTap() {
mEventTap = nullptr;
}
if (mEventTapSource) {
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mEventTapSource, kCFRunLoopCommonModes);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mEventTapSource,
kCFRunLoopCommonModes);
CFRelease(mEventTapSource);
mEventTapSource = nullptr;
}
}
CGEventRef MediaHardwareKeysEventSourceMac::EventTapCallback(CGEventTapProxy proxy,
CGEventType type, CGEventRef event,
void* refcon) {
CGEventRef MediaHardwareKeysEventSourceMac::EventTapCallback(
CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) {
// Re-enable event tap when receiving disabled events.
MediaHardwareKeysEventSourceMac* source = static_cast<MediaHardwareKeysEventSourceMac*>(refcon);
if (type == kCGEventTapDisabledByUserInput || type == kCGEventTapDisabledByTimeout) {
MediaHardwareKeysEventSourceMac* source =
static_cast<MediaHardwareKeysEventSourceMac*>(refcon);
if (type == kCGEventTapDisabledByUserInput ||
type == kCGEventTapDisabledByTimeout) {
MOZ_ASSERT(source->mEventTap);
CGEventTapEnable(source->mEventTap, true);
return event;
@ -151,8 +157,9 @@ CGEventRef MediaHardwareKeysEventSourceMac::EventTapCallback(CGEventTapProxy pro
// - keyRepeat = (keyFlags & 0x1);
const NSInteger data1 = [nsEvent data1];
int keyCode = (data1 & 0xFFFF0000) >> 16;
if (keyCode != NX_KEYTYPE_PLAY && keyCode != NX_KEYTYPE_NEXT && keyCode != NX_KEYTYPE_PREVIOUS &&
keyCode != NX_KEYTYPE_FAST && keyCode != NX_KEYTYPE_REWIND) {
if (keyCode != NX_KEYTYPE_PLAY && keyCode != NX_KEYTYPE_NEXT &&
keyCode != NX_KEYTYPE_PREVIOUS && keyCode != NX_KEYTYPE_FAST &&
keyCode != NX_KEYTYPE_REWIND) {
return event;
}
@ -173,7 +180,8 @@ CGEventRef MediaHardwareKeysEventSourceMac::EventTapCallback(CGEventTapProxy pro
}
LOG2("Get media key %s", source, ToMediaControlKeyStr(keyCode));
for (auto iter = source->mListeners.begin(); iter != source->mListeners.end(); ++iter) {
for (auto iter = source->mListeners.begin(); iter != source->mListeners.end();
++iter) {
(*iter)->OnActionPerformed(MediaControlAction(ToMediaControlKey(keyCode)));
}
return event;

Просмотреть файл

@ -13,39 +13,45 @@ using namespace mozilla::dom;
// avoid redefined macro in unified build
#undef LOG
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysEventSourceMacMediaCenter=%p, " msg, this, ##__VA_ARGS__))
#define LOG(msg, ...) \
MOZ_LOG(gMediaControlLog, LogLevel::Debug, \
("MediaHardwareKeysEventSourceMacMediaCenter=%p, " msg, this, \
##__VA_ARGS__))
namespace mozilla {
namespace widget {
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayPauseHandler() {
MediaCenterEventHandler
MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayPauseHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = center.playbackState == MPNowPlayingPlaybackStatePlaying
? MPNowPlayingPlaybackStatePaused
: MPNowPlayingPlaybackStatePlaying;
center.playbackState =
center.playbackState == MPNowPlayingPlaybackStatePlaying
? MPNowPlayingPlaybackStatePaused
: MPNowPlayingPlaybackStatePlaying;
HandleEvent(MediaControlKey::Playpause);
return MPRemoteCommandHandlerStatusSuccess;
});
}
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreateNextTrackHandler() {
MediaCenterEventHandler
MediaHardwareKeysEventSourceMacMediaCenter::CreateNextTrackHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
HandleEvent(MediaControlKey::Nexttrack);
return MPRemoteCommandHandlerStatusSuccess;
});
}
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePreviousTrackHandler() {
MediaCenterEventHandler
MediaHardwareKeysEventSourceMacMediaCenter::CreatePreviousTrackHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
HandleEvent(MediaControlKey::Previoustrack);
return MPRemoteCommandHandlerStatusSuccess;
});
}
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayHandler() {
MediaCenterEventHandler
MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
if (center.playbackState != MPNowPlayingPlaybackStatePlaying) {
@ -56,7 +62,8 @@ MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePlayHa
});
}
MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePauseHandler() {
MediaCenterEventHandler
MediaHardwareKeysEventSourceMacMediaCenter::CreatePauseHandler() {
return Block_copy(^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent* event) {
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
if (center.playbackState != MPNowPlayingPlaybackStatePaused) {
@ -67,7 +74,8 @@ MediaCenterEventHandler MediaHardwareKeysEventSourceMacMediaCenter::CreatePauseH
});
}
MediaHardwareKeysEventSourceMacMediaCenter::MediaHardwareKeysEventSourceMacMediaCenter() {
MediaHardwareKeysEventSourceMacMediaCenter::
MediaHardwareKeysEventSourceMacMediaCenter() {
mPlayPauseHandler = CreatePlayPauseHandler();
mNextTrackHandler = CreateNextTrackHandler();
mPreviousTrackHandler = CreatePreviousTrackHandler();
@ -76,7 +84,8 @@ MediaHardwareKeysEventSourceMacMediaCenter::MediaHardwareKeysEventSourceMacMedia
LOG("Create MediaHardwareKeysEventSourceMacMediaCenter");
}
MediaHardwareKeysEventSourceMacMediaCenter::~MediaHardwareKeysEventSourceMacMediaCenter() {
MediaHardwareKeysEventSourceMacMediaCenter::
~MediaHardwareKeysEventSourceMacMediaCenter() {
LOG("Destroy MediaHardwareKeysEventSourceMacMediaCenter");
EndListeningForEvents();
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
@ -86,13 +95,15 @@ MediaHardwareKeysEventSourceMacMediaCenter::~MediaHardwareKeysEventSourceMacMedi
void MediaHardwareKeysEventSourceMacMediaCenter::BeginListeningForEvents() {
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = MPNowPlayingPlaybackStatePlaying;
MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
MPRemoteCommandCenter* commandCenter =
[MPRemoteCommandCenter sharedCommandCenter];
commandCenter.togglePlayPauseCommand.enabled = true;
[commandCenter.togglePlayPauseCommand addTargetWithHandler:mPlayPauseHandler];
commandCenter.nextTrackCommand.enabled = true;
[commandCenter.nextTrackCommand addTargetWithHandler:mNextTrackHandler];
commandCenter.previousTrackCommand.enabled = true;
[commandCenter.previousTrackCommand addTargetWithHandler:mPreviousTrackHandler];
[commandCenter.previousTrackCommand
addTargetWithHandler:mPreviousTrackHandler];
commandCenter.playCommand.enabled = true;
[commandCenter.playCommand addTargetWithHandler:mPlayHandler];
commandCenter.pauseCommand.enabled = true;
@ -103,7 +114,8 @@ void MediaHardwareKeysEventSourceMacMediaCenter::EndListeningForEvents() {
MPNowPlayingInfoCenter* center = [MPNowPlayingInfoCenter defaultCenter];
center.playbackState = MPNowPlayingPlaybackStatePaused;
center.nowPlayingInfo = nil;
MPRemoteCommandCenter* commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
MPRemoteCommandCenter* commandCenter =
[MPRemoteCommandCenter sharedCommandCenter];
commandCenter.togglePlayPauseCommand.enabled = false;
[commandCenter.togglePlayPauseCommand removeTarget:nil];
commandCenter.nextTrackCommand.enabled = false;
@ -131,9 +143,12 @@ void MediaHardwareKeysEventSourceMacMediaCenter::Close() {
MediaControlKeySource::Close();
}
bool MediaHardwareKeysEventSourceMacMediaCenter::IsOpened() const { return mOpened; }
bool MediaHardwareKeysEventSourceMacMediaCenter::IsOpened() const {
return mOpened;
}
void MediaHardwareKeysEventSourceMacMediaCenter::HandleEvent(MediaControlKey aEvent) {
void MediaHardwareKeysEventSourceMacMediaCenter::HandleEvent(
MediaControlKey aEvent) {
for (auto iter = mListeners.begin(); iter != mListeners.end(); ++iter) {
(*iter)->OnActionPerformed(MediaControlAction(aEvent));
}

Просмотреть файл

@ -56,12 +56,16 @@ void NativeKeyBindings::Shutdown() {
NativeKeyBindings::NativeKeyBindings() {}
inline objc_selector* ToObjcSelectorPtr(SEL aSel) { return reinterpret_cast<objc_selector*>(aSel); }
#define SEL_TO_COMMAND(aSel, aCommand) \
mSelectorToCommand.InsertOrUpdate(ToObjcSelectorPtr(@selector(aSel)), aCommand)
inline objc_selector* ToObjcSelectorPtr(SEL aSel) {
return reinterpret_cast<objc_selector*>(aSel);
}
#define SEL_TO_COMMAND(aSel, aCommand) \
mSelectorToCommand.InsertOrUpdate(ToObjcSelectorPtr(@selector(aSel)), \
aCommand)
void NativeKeyBindings::Init(NativeKeyBindingsType aType) {
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info, ("%p NativeKeyBindings::Init", this));
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info,
("%p NativeKeyBindings::Init", this));
// Many selectors have a one-to-one mapping to a Gecko command. Those mappings
// are registered in mSelectorToCommand.
@ -88,7 +92,8 @@ void NativeKeyBindings::Init(NativeKeyBindingsType aType) {
// TODO: deleteTo* selectors are also supposed to add text to a kill buffer
SEL_TO_COMMAND(deleteToBeginningOfLine:, Command::DeleteToBeginningOfLine);
SEL_TO_COMMAND(deleteToBeginningOfParagraph:, Command::DeleteToBeginningOfLine);
SEL_TO_COMMAND(deleteToBeginningOfParagraph:,
Command::DeleteToBeginningOfLine);
SEL_TO_COMMAND(deleteToEndOfLine:, Command::DeleteToEndOfLine);
SEL_TO_COMMAND(deleteToEndOfParagraph:, Command::DeleteToEndOfLine);
// SEL_TO_COMMAND(deleteToMark:, );
@ -119,26 +124,34 @@ void NativeKeyBindings::Init(NativeKeyBindingsType aType) {
SEL_TO_COMMAND(moveForwardAndModifySelection:, Command::SelectCharNext);
SEL_TO_COMMAND(moveLeft:, Command::CharPrevious);
SEL_TO_COMMAND(moveLeftAndModifySelection:, Command::SelectCharPrevious);
SEL_TO_COMMAND(moveParagraphBackwardAndModifySelection:, Command::SelectBeginLine);
SEL_TO_COMMAND(moveParagraphForwardAndModifySelection:, Command::SelectEndLine);
SEL_TO_COMMAND(moveParagraphBackwardAndModifySelection:,
Command::SelectBeginLine);
SEL_TO_COMMAND(moveParagraphForwardAndModifySelection:,
Command::SelectEndLine);
SEL_TO_COMMAND(moveRight:, Command::CharNext);
SEL_TO_COMMAND(moveRightAndModifySelection:, Command::SelectCharNext);
SEL_TO_COMMAND(moveToBeginningOfDocument:, Command::MoveTop);
SEL_TO_COMMAND(moveToBeginningOfDocumentAndModifySelection:, Command::SelectTop);
SEL_TO_COMMAND(moveToBeginningOfDocumentAndModifySelection:,
Command::SelectTop);
SEL_TO_COMMAND(moveToBeginningOfLine:, Command::BeginLine);
SEL_TO_COMMAND(moveToBeginningOfLineAndModifySelection:, Command::SelectBeginLine);
SEL_TO_COMMAND(moveToBeginningOfLineAndModifySelection:,
Command::SelectBeginLine);
SEL_TO_COMMAND(moveToBeginningOfParagraph:, Command::BeginLine);
SEL_TO_COMMAND(moveToBeginningOfParagraphAndModifySelection:, Command::SelectBeginLine);
SEL_TO_COMMAND(moveToBeginningOfParagraphAndModifySelection:,
Command::SelectBeginLine);
SEL_TO_COMMAND(moveToEndOfDocument:, Command::MoveBottom);
SEL_TO_COMMAND(moveToEndOfDocumentAndModifySelection:, Command::SelectBottom);
SEL_TO_COMMAND(moveToEndOfLine:, Command::EndLine);
SEL_TO_COMMAND(moveToEndOfLineAndModifySelection:, Command::SelectEndLine);
SEL_TO_COMMAND(moveToEndOfParagraph:, Command::EndLine);
SEL_TO_COMMAND(moveToEndOfParagraphAndModifySelection:, Command::SelectEndLine);
SEL_TO_COMMAND(moveToEndOfParagraphAndModifySelection:,
Command::SelectEndLine);
SEL_TO_COMMAND(moveToLeftEndOfLine:, Command::BeginLine);
SEL_TO_COMMAND(moveToLeftEndOfLineAndModifySelection:, Command::SelectBeginLine);
SEL_TO_COMMAND(moveToLeftEndOfLineAndModifySelection:,
Command::SelectBeginLine);
SEL_TO_COMMAND(moveToRightEndOfLine:, Command::EndLine);
SEL_TO_COMMAND(moveToRightEndOfLineAndModifySelection:, Command::SelectEndLine);
SEL_TO_COMMAND(moveToRightEndOfLineAndModifySelection:,
Command::SelectEndLine);
if (aType == NativeKeyBindingsType::SingleLineEditor) {
SEL_TO_COMMAND(moveUp:, Command::BeginLine);
} else {
@ -146,7 +159,8 @@ void NativeKeyBindings::Init(NativeKeyBindingsType aType) {
}
SEL_TO_COMMAND(moveUpAndModifySelection:, Command::SelectLinePrevious);
SEL_TO_COMMAND(moveWordBackward:, Command::WordPrevious);
SEL_TO_COMMAND(moveWordBackwardAndModifySelection:, Command::SelectWordPrevious);
SEL_TO_COMMAND(moveWordBackwardAndModifySelection:,
Command::SelectWordPrevious);
SEL_TO_COMMAND(moveWordForward:, Command::WordNext);
SEL_TO_COMMAND(moveWordForwardAndModifySelection:, Command::SelectWordNext);
SEL_TO_COMMAND(moveWordLeft:, Command::WordPrevious);
@ -191,7 +205,8 @@ void NativeKeyBindings::GetEditCommands(const WidgetKeyboardEvent& aEvent,
MOZ_ASSERT(!aEvent.mFlags.mIsSynthesizedForTests);
MOZ_ASSERT(aCommands.IsEmpty());
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info, ("%p NativeKeyBindings::GetEditCommands", this));
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info,
("%p NativeKeyBindings::GetEditCommands", this));
// Recover the current event, which should always be the key down we are
// responding to.
@ -200,7 +215,8 @@ void NativeKeyBindings::GetEditCommands(const WidgetKeyboardEvent& aEvent,
if (!cocoaEvent || [cocoaEvent type] != NSEventTypeKeyDown) {
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info,
("%p NativeKeyBindings::GetEditCommands, no Cocoa key down event", this));
("%p NativeKeyBindings::GetEditCommands, no Cocoa key down event",
this));
return;
}
@ -210,7 +226,8 @@ void NativeKeyBindings::GetEditCommands(const WidgetKeyboardEvent& aEvent,
NSEvent* originalEvent = cocoaEvent;
// TODO: Use KeyNameIndex rather than legacy keyCode.
uint32_t remappedGeckoKeyCode = aEvent.GetRemappedKeyCode(aWritingMode.ref());
uint32_t remappedGeckoKeyCode =
aEvent.GetRemappedKeyCode(aWritingMode.ref());
uint32_t remappedCocoaKeyCode = 0;
switch (remappedGeckoKeyCode) {
case NS_VK_UP:
@ -229,8 +246,10 @@ void NativeKeyBindings::GetEditCommands(const WidgetKeyboardEvent& aEvent,
MOZ_ASSERT_UNREACHABLE("Add a case for the new remapped key");
return;
}
unichar ch = nsCocoaUtils::ConvertGeckoKeyCodeToMacCharCode(remappedGeckoKeyCode);
NSString* chars = [[[NSString alloc] initWithCharacters:&ch length:1] autorelease];
unichar ch =
nsCocoaUtils::ConvertGeckoKeyCodeToMacCharCode(remappedGeckoKeyCode);
NSString* chars = [[[NSString alloc] initWithCharacters:&ch
length:1] autorelease];
cocoaEvent = [NSEvent keyEventWithType:[originalEvent type]
location:[originalEvent locationInWindow]
modifierFlags:[originalEvent modifierFlags]
@ -272,11 +291,12 @@ void NativeKeyBindings::GetEditCommands(const WidgetKeyboardEvent& aEvent,
LogEditCommands(aCommands, "NativeKeyBindings::GetEditCommands");
}
void NativeKeyBindings::AppendEditCommandsForSelector(objc_selector* aSelector,
nsTArray<CommandInt>& aCommands) const {
void NativeKeyBindings::AppendEditCommandsForSelector(
objc_selector* aSelector, nsTArray<CommandInt>& aCommands) const {
// Try to find a simple mapping in the hashtable
Command geckoCommand = Command::DoNothing;
if (mSelectorToCommand.Get(aSelector, &geckoCommand) && geckoCommand != Command::DoNothing) {
if (mSelectorToCommand.Get(aSelector, &geckoCommand) &&
geckoCommand != Command::DoNothing) {
aCommands.AppendElement(static_cast<CommandInt>(geckoCommand));
} else if (aSelector == ToObjcSelectorPtr(@selector(selectLine:))) {
// This is functional, but Cocoa's version is direction-less in that
@ -300,7 +320,8 @@ void NativeKeyBindings::LogEditCommands(const nsTArray<CommandInt>& aCommands,
}
if (aCommands.IsEmpty()) {
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info, ("%p %s, no edit commands", this, aDescription));
MOZ_LOG(gNativeKeyBindingsLog, LogLevel::Info,
("%p %s, no edit commands", this, aDescription));
return;
}
@ -313,10 +334,9 @@ void NativeKeyBindings::LogEditCommands(const nsTArray<CommandInt>& aCommands,
}
// static
void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
const WidgetKeyboardEvent& aEvent,
const Maybe<WritingMode>& aWritingMode,
nsTArray<CommandInt>& aCommands) {
void NativeKeyBindings::GetEditCommandsForTests(
NativeKeyBindingsType aType, const WidgetKeyboardEvent& aEvent,
const Maybe<WritingMode>& aWritingMode, nsTArray<CommandInt>& aCommands) {
MOZ_DIAGNOSTIC_ASSERT(aEvent.IsTrusted());
// The following mapping is checked on Big Sur. Some of them are defined in:
@ -325,8 +345,9 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
if (NS_WARN_IF(!instance)) {
return;
}
switch (aWritingMode.isSome() ? aEvent.GetRemappedKeyNameIndex(aWritingMode.ref())
: aEvent.mKeyNameIndex) {
switch (aWritingMode.isSome()
? aEvent.GetRemappedKeyNameIndex(aWritingMode.ref())
: aEvent.mKeyNameIndex) {
case KEY_NAME_INDEX_USE_STRING:
if (!aEvent.IsControl() || aEvent.IsAlt() || aEvent.IsMeta()) {
break;
@ -337,21 +358,23 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToBeginningOfParagraph:))
: ToObjcSelectorPtr(@selector(moveToBeginningOfParagraphAndModifySelection:)),
: ToObjcSelectorPtr(@selector(
moveToBeginningOfParagraphAndModifySelection:)),
aCommands);
break;
case 'b':
case 'B':
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveBackward:))
: ToObjcSelectorPtr(@selector(moveBackwardAndModifySelection:)),
: ToObjcSelectorPtr(@selector(
moveBackwardAndModifySelection:)),
aCommands);
break;
case 'd':
case 'D':
if (!aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteForward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteForward:)), aCommands);
}
break;
case 'e':
@ -359,42 +382,47 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToEndOfParagraph:))
: ToObjcSelectorPtr(@selector(moveToEndOfParagraphAndModifySelection:)),
: ToObjcSelectorPtr(
@selector(moveToEndOfParagraphAndModifySelection:)),
aCommands);
break;
case 'f':
case 'F':
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveForward:))
: ToObjcSelectorPtr(@selector(moveForwardAndModifySelection:)),
: ToObjcSelectorPtr(@selector(
moveForwardAndModifySelection:)),
aCommands);
break;
case 'h':
case 'H':
if (!aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteBackward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteBackward:)), aCommands);
}
break;
case 'k':
case 'K':
if (!aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteToEndOfParagraph:)), aCommands);
ToObjcSelectorPtr(@selector(deleteToEndOfParagraph:)),
aCommands);
}
break;
case 'n':
case 'N':
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveDown:))
: ToObjcSelectorPtr(@selector(moveDownAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveDown:))
: ToObjcSelectorPtr(@selector(moveDownAndModifySelection:)),
aCommands);
break;
case 'p':
case 'P':
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveUp:))
: ToObjcSelectorPtr(@selector(moveUpAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveUp:))
: ToObjcSelectorPtr(@selector(moveUpAndModifySelection:)),
aCommands);
break;
default:
@ -413,21 +441,22 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
}
if (aEvent.IsAlt()) {
// Shift and Control are ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteWordBackward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteWordBackward:)), aCommands);
break;
}
if (aEvent.IsControl()) {
if (aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteBackwardByDecomposingPreviousCharacter:)),
ToObjcSelectorPtr(
@selector(deleteBackwardByDecomposingPreviousCharacter:)),
aCommands);
}
break;
}
// Shift is ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteBackward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteBackward:)), aCommands);
break;
case KEY_NAME_INDEX_Delete:
if (aEvent.IsControl() || aEvent.IsMeta()) {
@ -435,13 +464,13 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
}
if (aEvent.IsAlt()) {
// Shift is ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteWordForward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteWordForward:)), aCommands);
break;
}
// Shift is ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(deleteForward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(deleteForward:)), aCommands);
break;
case KEY_NAME_INDEX_PageDown:
if (aEvent.IsControl() || aEvent.IsMeta()) {
@ -449,12 +478,14 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
}
if (aEvent.IsAlt()) {
// Shift is ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(pageDown:)), aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(pageDown:)), aCommands);
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(scrollPageDown:))
: ToObjcSelectorPtr(@selector(pageDownAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(scrollPageDown:))
: ToObjcSelectorPtr(@selector(pageDownAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_PageUp:
@ -463,12 +494,14 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
}
if (aEvent.IsAlt()) {
// Shift is ignored.
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(pageUp:)), aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(pageUp:)), aCommands);
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(scrollPageUp:))
: ToObjcSelectorPtr(@selector(pageUpAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(scrollPageUp:))
: ToObjcSelectorPtr(@selector(pageUpAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_Home:
@ -478,7 +511,8 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(scrollToBeginningOfDocument:))
: ToObjcSelectorPtr(@selector(moveToBeginningOfDocumentAndModifySelection:)),
: ToObjcSelectorPtr(
@selector(moveToBeginningOfDocumentAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_End:
@ -486,8 +520,10 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(scrollToEndOfDocument:))
: ToObjcSelectorPtr(@selector(moveToEndOfDocumentAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(scrollToEndOfDocument:))
: ToObjcSelectorPtr(@selector
(moveToEndOfDocumentAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_ArrowLeft:
@ -498,7 +534,8 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToLeftEndOfLine:))
: ToObjcSelectorPtr(@selector(moveToLeftEndOfLineAndModifySelection:)),
: ToObjcSelectorPtr(@selector
(moveToLeftEndOfLineAndModifySelection:)),
aCommands);
break;
}
@ -506,8 +543,9 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveLeft:))
: ToObjcSelectorPtr(@selector(moveLeftAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveLeft:))
: ToObjcSelectorPtr(@selector(moveLeftAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_ArrowRight:
@ -518,7 +556,8 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToRightEndOfLine:))
: ToObjcSelectorPtr(@selector(moveToRightEndOfLineAndModifySelection:)),
: ToObjcSelectorPtr(@selector
(moveToRightEndOfLineAndModifySelection:)),
aCommands);
break;
}
@ -526,8 +565,9 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveRight:))
: ToObjcSelectorPtr(@selector(moveRightAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveRight:))
: ToObjcSelectorPtr(@selector(moveRightAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_ArrowUp:
@ -541,25 +581,30 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToBeginningOfDocument:))
: ToObjcSelectorPtr(@selector(moveToBegginingOfDocumentAndModifySelection:)),
: ToObjcSelectorPtr(
@selector(moveToBegginingOfDocumentAndModifySelection:)),
aCommands);
break;
}
if (aEvent.IsAlt()) {
if (!aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(moveBackward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveToBeginningOfParagraph:)), aCommands);
ToObjcSelectorPtr(@selector(moveBackward:)), aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveToBeginningOfParagraph:)),
aCommands);
break;
}
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveParagraphBackwardAndModifySelection:)), aCommands);
ToObjcSelectorPtr(@selector
(moveParagraphBackwardAndModifySelection:)),
aCommands);
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveUp:))
: ToObjcSelectorPtr(@selector(moveUpAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveUp:))
: ToObjcSelectorPtr(@selector(moveUpAndModifySelection:)),
aCommands);
break;
case KEY_NAME_INDEX_ArrowDown:
@ -573,32 +618,37 @@ void NativeKeyBindings::GetEditCommandsForTests(NativeKeyBindingsType aType,
instance->AppendEditCommandsForSelector(
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveToEndOfDocument:))
: ToObjcSelectorPtr(@selector(moveToEndOfDocumentAndModifySelection:)),
: ToObjcSelectorPtr(@selector
(moveToEndOfDocumentAndModifySelection:)),
aCommands);
break;
}
if (aEvent.IsAlt()) {
if (!aEvent.IsShift()) {
instance->AppendEditCommandsForSelector(ToObjcSelectorPtr(@selector(moveForward:)),
aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveForward:)), aCommands);
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveToEndOfParagraph:)), aCommands);
break;
}
instance->AppendEditCommandsForSelector(
ToObjcSelectorPtr(@selector(moveParagraphForwardAndModifySelection:)), aCommands);
ToObjcSelectorPtr(@selector
(moveParagraphForwardAndModifySelection:)),
aCommands);
break;
}
instance->AppendEditCommandsForSelector(
!aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveDown:))
: ToObjcSelectorPtr(@selector(moveDownAndModifySelection:)),
!aEvent.IsShift()
? ToObjcSelectorPtr(@selector(moveDown:))
: ToObjcSelectorPtr(@selector(moveDownAndModifySelection:)),
aCommands);
break;
default:
break;
}
instance->LogEditCommands(aCommands, "NativeKeyBindings::GetEditCommandsForTests");
instance->LogEditCommands(aCommands,
"NativeKeyBindings::GetEditCommandsForTests");
}
} // namespace widget

Просмотреть файл

@ -37,7 +37,8 @@ namespace widget {
NativeMenuMac::NativeMenuMac(dom::Element* aElement)
: mElement(aElement), mContainerStatusBarItem(nil) {
MOZ_RELEASE_ASSERT(aElement->IsAnyOfXULElements(nsGkAtoms::menu, nsGkAtoms::menupopup));
MOZ_RELEASE_ASSERT(
aElement->IsAnyOfXULElements(nsGkAtoms::menu, nsGkAtoms::menupopup));
mMenuGroupOwner = new nsMenuGroupOwnerX(aElement, nullptr);
mMenu = MakeRefPtr<nsMenuX>(nullptr, mMenuGroupOwner, aElement);
mMenu->SetObserver(this);
@ -78,9 +79,11 @@ bool NativeMenuMac::ActivateNativeMenuItemAt(const nsAString& aIndexString) {
nsMenuUtilsX::CheckNativeMenuConsistency(menu);
NSString* locationString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(aIndexString.BeginReading())
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
aIndexString.BeginReading())
length:aIndexString.Length()];
NSMenuItem* item = nsMenuUtilsX::NativeMenuItemWithLocation(menu, locationString, false);
NSMenuItem* item =
nsMenuUtilsX::NativeMenuItemWithLocation(menu, locationString, false);
// We can't perform an action on an item with a submenu, that will raise
// an obj-c exception.
@ -106,9 +109,11 @@ void NativeMenuMac::ForceUpdateNativeMenuAt(const nsAString& aIndexString) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSString* locationString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(aIndexString.BeginReading())
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
aIndexString.BeginReading())
length:aIndexString.Length()];
NSArray<NSString*>* indexes = [locationString componentsSeparatedByString:@"|"];
NSArray<NSString*>* indexes =
[locationString componentsSeparatedByString:@"|"];
RefPtr<nsMenuX> currentMenu = mMenu.get();
// now find the correct submenu
@ -124,7 +129,9 @@ void NativeMenuMac::ForceUpdateNativeMenuAt(const nsAString& aIndexString) {
}
RefPtr<nsIContent> content = targetMenu->match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
if (!nsMenuUtilsX::NodeIsHiddenOrCollapsed(content)) {
visible++;
if (targetMenu->is<RefPtr<nsMenuX>>() && visible == (targetIndex + 1)) {
@ -175,8 +182,8 @@ void NativeMenuMac::OnMenuWillOpen(dom::Element* aPopupElement) {
return;
}
// Our caller isn't keeping us alive, so make sure we stay alive throughout this function in case
// one of the observer notifications destroys us.
// Our caller isn't keeping us alive, so make sure we stay alive throughout
// this function in case one of the observer notifications destroys us.
RefPtr<NativeMenuMac> kungFuDeathGrip(this);
for (NativeMenu::Observer* observer : mObservers.Clone()) {
@ -185,8 +192,8 @@ void NativeMenuMac::OnMenuWillOpen(dom::Element* aPopupElement) {
}
void NativeMenuMac::OnMenuDidOpen(dom::Element* aPopupElement) {
// Our caller isn't keeping us alive, so make sure we stay alive throughout this function in case
// one of the observer notifications destroys us.
// Our caller isn't keeping us alive, so make sure we stay alive throughout
// this function in case one of the observer notifications destroys us.
RefPtr<NativeMenuMac> kungFuDeathGrip(this);
for (NativeMenu::Observer* observer : mObservers.Clone()) {
@ -200,8 +207,8 @@ void NativeMenuMac::OnMenuDidOpen(dom::Element* aPopupElement) {
void NativeMenuMac::OnMenuWillActivateItem(dom::Element* aPopupElement,
dom::Element* aMenuItemElement) {
// Our caller isn't keeping us alive, so make sure we stay alive throughout this function in case
// one of the observer notifications destroys us.
// Our caller isn't keeping us alive, so make sure we stay alive throughout
// this function in case one of the observer notifications destroys us.
RefPtr<NativeMenuMac> kungFuDeathGrip(this);
for (NativeMenu::Observer* observer : mObservers.Clone()) {
@ -210,8 +217,8 @@ void NativeMenuMac::OnMenuWillActivateItem(dom::Element* aPopupElement,
}
void NativeMenuMac::OnMenuClosed(dom::Element* aPopupElement) {
// Our caller isn't keeping us alive, so make sure we stay alive throughout this function in case
// one of the observer notifications destroys us.
// Our caller isn't keeping us alive, so make sure we stay alive throughout
// this function in case one of the observer notifications destroys us.
RefPtr<NativeMenuMac> kungFuDeathGrip(this);
for (NativeMenu::Observer* observer : mObservers.Clone()) {
@ -236,7 +243,8 @@ static NSAppearance* NativeAppearanceForContent(nsIContent* aContent) {
return NSAppearanceForColorScheme(LookAndFeel::ColorSchemeForFrame(f));
}
void NativeMenuMac::ShowAsContextMenu(nsIFrame* aClickedFrame, const CSSIntPoint& aPosition,
void NativeMenuMac::ShowAsContextMenu(nsIFrame* aClickedFrame,
const CSSIntPoint& aPosition,
bool aIsContextMenu) {
nsPresContext* pc = aClickedFrame->PresContext();
auto cssToDesktopScale =
@ -250,24 +258,29 @@ void NativeMenuMac::ShowAsContextMenu(nsIFrame* aClickedFrame, const CSSIntPoint
NSAppearance* appearance = NativeAppearanceForContent(mMenu->Content());
NSPoint locationOnScreen = nsCocoaUtils::GeckoPointToCocoaPoint(desktopPoint);
// Let the MOZMenuOpeningCoordinator do the actual opening, so that this ShowAsContextMenu call
// does not spawn a nested event loop, which would be surprising to our callers.
mOpeningHandle = [MOZMenuOpeningCoordinator.sharedInstance asynchronouslyOpenMenu:menu
atScreenPosition:locationOnScreen
forView:view
withAppearance:appearance
asContextMenu:aIsContextMenu];
// Let the MOZMenuOpeningCoordinator do the actual opening, so that this
// ShowAsContextMenu call does not spawn a nested event loop, which would be
// surprising to our callers.
mOpeningHandle = [MOZMenuOpeningCoordinator.sharedInstance
asynchronouslyOpenMenu:menu
atScreenPosition:locationOnScreen
forView:view
withAppearance:appearance
asContextMenu:aIsContextMenu];
}
bool NativeMenuMac::Close() {
if (mOpeningHandle) {
// In case the menu was trying to open, but this Close() call interrupted it, cancel opening.
[MOZMenuOpeningCoordinator.sharedInstance cancelAsynchronousOpening:mOpeningHandle];
// In case the menu was trying to open, but this Close() call interrupted
// it, cancel opening.
[MOZMenuOpeningCoordinator.sharedInstance
cancelAsynchronousOpening:mOpeningHandle];
}
return mMenu->Close();
}
RefPtr<nsMenuX> NativeMenuMac::GetOpenMenuContainingElement(dom::Element* aElement) {
RefPtr<nsMenuX> NativeMenuMac::GetOpenMenuContainingElement(
dom::Element* aElement) {
nsTArray<RefPtr<dom::Element>> submenuChain;
RefPtr<dom::Element> currentElement = aElement->GetParentElement();
while (currentElement && currentElement != mElement) {
@ -281,7 +294,8 @@ RefPtr<nsMenuX> NativeMenuMac::GetOpenMenuContainingElement(dom::Element* aEleme
return nullptr;
}
// Traverse submenuChain from shallow to deep, to find the nsMenuX that contains aElement.
// Traverse submenuChain from shallow to deep, to find the nsMenuX that
// contains aElement.
submenuChain.Reverse();
RefPtr<nsMenuX> menu = mMenu;
for (const auto& submenu : submenuChain) {
@ -321,7 +335,8 @@ static NSEventModifierFlags ConvertModifierFlags(Modifiers aModifiers) {
return flags;
}
void NativeMenuMac::ActivateItem(dom::Element* aItemElement, Modifiers aModifiers, int16_t aButton,
void NativeMenuMac::ActivateItem(dom::Element* aItemElement,
Modifiers aModifiers, int16_t aButton,
ErrorResult& aRv) {
RefPtr<nsMenuX> menu = GetOpenMenuContainingElement(aItemElement);
if (!menu) {
@ -343,27 +358,29 @@ void NativeMenuMac::ActivateItem(dom::Element* aItemElement, Modifiers aModifier
NSMenuItem* nativeItem = [item->NativeNSMenuItem() retain];
// First, initiate the closing of the NSMenu.
// This synchronously calls the menu delegate's menuDidClose handler. So menuDidClose is
// what runs first; this matches the order of events for user-initiated menu item activation.
// This call doesn't immediately hide the menu; the menu only hides once the stack unwinds
// from NSMenu's nested "tracking" event loop.
// This synchronously calls the menu delegate's menuDidClose handler. So
// menuDidClose is what runs first; this matches the order of events for
// user-initiated menu item activation. This call doesn't immediately hide the
// menu; the menu only hides once the stack unwinds from NSMenu's nested
// "tracking" event loop.
[mMenu->NativeNSMenu() cancelTrackingWithoutAnimation];
// Next, call OnWillActivateItem. This also matches the order of calls that happen when a user
// activates a menu item in the real world: -[MenuDelegate menu:willActivateItem:] runs after
// menuDidClose.
// Next, call OnWillActivateItem. This also matches the order of calls that
// happen when a user activates a menu item in the real world: -[MenuDelegate
// menu:willActivateItem:] runs after menuDidClose.
menu->OnWillActivateItem(nativeItem);
// Finally, call ActivateItemAfterClosing. This also mimics the order in the real world:
// menuItemHit is called after menu:willActivateItem:.
menu->ActivateItemAfterClosing(std::move(item), ConvertModifierFlags(aModifiers), aButton);
// Finally, call ActivateItemAfterClosing. This also mimics the order in the
// real world: menuItemHit is called after menu:willActivateItem:.
menu->ActivateItemAfterClosing(std::move(item),
ConvertModifierFlags(aModifiers), aButton);
// Tell our native event loop that it should not process any more work before
// unwinding the stack, so that we can get out of the menu's nested event loop
// as fast as possible. This was needed to fix spurious failures in tests, where
// a call to cancelTrackingWithoutAnimation was ignored if more native events were
// processed before the event loop was exited. As a result, the menu stayed open
// forever and the test never finished.
// as fast as possible. This was needed to fix spurious failures in tests,
// where a call to cancelTrackingWithoutAnimation was ignored if more native
// events were processed before the event loop was exited. As a result, the
// menu stayed open forever and the test never finished.
MOZMenuOpeningCoordinator.needToUnwindForMenuClosing = YES;
[nativeItem release];

Просмотреть файл

@ -14,14 +14,19 @@
namespace mozilla::widget {
void NativeMenuSupport::CreateNativeMenuBar(nsIWidget* aParent, dom::Element* aMenuBarElement) {
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Attempting to create native menu bar on wrong thread!");
void NativeMenuSupport::CreateNativeMenuBar(nsIWidget* aParent,
dom::Element* aMenuBarElement) {
MOZ_RELEASE_ASSERT(NS_IsMainThread(),
"Attempting to create native menu bar on wrong thread!");
// Create the menubar and give it to the parent window. The parent takes ownership.
static_cast<nsCocoaWindow*>(aParent)->SetMenuBar(MakeRefPtr<nsMenuBarX>(aMenuBarElement));
// Create the menubar and give it to the parent window. The parent takes
// ownership.
static_cast<nsCocoaWindow*>(aParent)->SetMenuBar(
MakeRefPtr<nsMenuBarX>(aMenuBarElement));
}
already_AddRefed<NativeMenu> NativeMenuSupport::CreateNativeContextMenu(dom::Element* aPopup) {
already_AddRefed<NativeMenu> NativeMenuSupport::CreateNativeContextMenu(
dom::Element* aPopup) {
return MakeAndAddRef<NativeMenuMac>(aPopup);
}

Просмотреть файл

@ -55,7 +55,8 @@ using namespace mozilla;
- (void)_removeDisplayedNotification:(id<FakeNSUserNotification>)notification;
@end
@interface mozNotificationCenterDelegate : NSObject <NSUserNotificationCenterDelegate> {
@interface mozNotificationCenterDelegate
: NSObject <NSUserNotificationCenterDelegate> {
OSXNotificationCenter* mOSXNC;
}
- (id)initWithOSXNC:(OSXNotificationCenter*)osxnc;
@ -78,11 +79,12 @@ using namespace mozilla;
didActivateNotification:(id<FakeNSUserNotification>)notification {
unsigned long long additionalActionIndex = ULLONG_MAX;
if ([notification respondsToSelector:@selector(_alternateActionIndex)]) {
NSNumber* alternateActionIndex = [(NSObject*)notification valueForKey:@"_alternateActionIndex"];
NSNumber* alternateActionIndex =
[(NSObject*)notification valueForKey:@"_alternateActionIndex"];
additionalActionIndex = [alternateActionIndex unsignedLongLongValue];
}
mOSXNC->OnActivate([[notification userInfo] valueForKey:@"name"], notification.activationType,
additionalActionIndex);
mOSXNC->OnActivate([[notification userInfo] valueForKey:@"name"],
notification.activationType, additionalActionIndex);
}
- (BOOL)userNotificationCenter:(id<FakeNSUserNotificationCenter>)center
@ -100,7 +102,8 @@ using namespace mozilla;
}
}
// This is an undocumented method that we need to be notified if a user clicks the close button.
// This is an undocumented method that we need to be notified if a user clicks
// the close button.
- (void)userNotificationCenter:(id<FakeNSUserNotificationCenter>)center
didDismissAlert:(id<FakeNSUserNotification>)notification {
NSString* name = [[notification userInfo] valueForKey:@"name"];
@ -122,7 +125,8 @@ class OSXNotificationInfo final : public nsISupports {
public:
NS_DECL_ISUPPORTS
OSXNotificationInfo(NSString* name, nsIObserver* observer, const nsAString& alertCookie);
OSXNotificationInfo(NSString* name, nsIObserver* observer,
const nsAString& alertCookie);
NSString* mName;
nsCOMPtr<nsIObserver> mObserver;
@ -183,50 +187,56 @@ OSXNotificationCenter::~OSXNotificationCenter() {
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
NS_IMPL_ISUPPORTS(OSXNotificationCenter, nsIAlertsService, nsIAlertsIconData, nsIAlertsDoNotDisturb,
nsIAlertNotificationImageListener)
NS_IMPL_ISUPPORTS(OSXNotificationCenter, nsIAlertsService, nsIAlertsIconData,
nsIAlertsDoNotDisturb, nsIAlertNotificationImageListener)
nsresult OSXNotificationCenter::Init() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return (!!NSClassFromString(@"NSUserNotification")) ? NS_OK : NS_ERROR_FAILURE;
return (!!NSClassFromString(@"NSUserNotification")) ? NS_OK
: NS_ERROR_FAILURE;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
NS_IMETHODIMP
OSXNotificationCenter::ShowAlertNotification(
const nsAString& aImageUrl, const nsAString& aAlertTitle, const nsAString& aAlertText,
bool aAlertTextClickable, const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aAlertName, const nsAString& aBidi, const nsAString& aLang,
const nsAString& aData, nsIPrincipal* aPrincipal, bool aInPrivateBrowsing,
bool aRequireInteraction) {
nsCOMPtr<nsIAlertNotification> alert = do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
NS_ENSURE_TRUE(alert, NS_ERROR_FAILURE);
// vibrate is unused for now
nsTArray<uint32_t> vibrate;
nsresult rv = alert->Init(aAlertName, aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aBidi, aLang, aData, aPrincipal, aInPrivateBrowsing,
nsresult rv = alert->Init(aAlertName, aImageUrl, aAlertTitle, aAlertText,
aAlertTextClickable, aAlertCookie, aBidi, aLang,
aData, aPrincipal, aInPrivateBrowsing,
aRequireInteraction, false, vibrate);
NS_ENSURE_SUCCESS(rv, rv);
return ShowAlert(alert, aAlertListener);
}
NS_IMETHODIMP
OSXNotificationCenter::ShowPersistentNotification(const nsAString& aPersistentData,
nsIAlertNotification* aAlert,
nsIObserver* aAlertListener) {
OSXNotificationCenter::ShowPersistentNotification(
const nsAString& aPersistentData, nsIAlertNotification* aAlert,
nsIObserver* aAlertListener) {
return ShowAlert(aAlert, aAlertListener);
}
NS_IMETHODIMP
OSXNotificationCenter::ShowAlert(nsIAlertNotification* aAlert, nsIObserver* aAlertListener) {
OSXNotificationCenter::ShowAlert(nsIAlertNotification* aAlert,
nsIObserver* aAlertListener) {
return ShowAlertWithIconData(aAlert, aAlertListener, 0, nullptr);
}
NS_IMETHODIMP
OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
nsIObserver* aAlertListener, uint32_t aIconSize,
nsIObserver* aAlertListener,
uint32_t aIconSize,
const uint8_t* aIconData) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@ -248,13 +258,16 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
rv = aAlert->GetSource(hostPort);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundle> bundle;
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
nsCOMPtr<nsIStringBundleService> sbs =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
sbs->CreateBundle("chrome://alerts/locale/alert.properties",
getter_AddRefs(bundle));
if (!hostPort.IsEmpty() && bundle) {
AutoTArray<nsString, 1> formatStrings = {hostPort};
nsAutoString notificationSource;
bundle->FormatStringFromName("source.label", formatStrings, notificationSource);
bundle->FormatStringFromName("source.label", formatStrings,
notificationSource);
notification.subtitle = nsCocoaUtils::ToNSString(notificationSource);
}
@ -268,17 +281,19 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
notification.soundName = isSilent ? nil : NSUserNotificationDefaultSoundName;
notification.hasActionButton = NO;
// If this is not an application/extension alert, show additional actions dealing with
// permissions.
// If this is not an application/extension alert, show additional actions
// dealing with permissions.
bool isActionable;
if (bundle && NS_SUCCEEDED(aAlert->GetActionable(&isActionable)) && isActionable) {
nsAutoString closeButtonTitle, actionButtonTitle, disableButtonTitle, settingsButtonTitle;
if (bundle && NS_SUCCEEDED(aAlert->GetActionable(&isActionable)) &&
isActionable) {
nsAutoString closeButtonTitle, actionButtonTitle, disableButtonTitle,
settingsButtonTitle;
bundle->GetStringFromName("closeButton.title", closeButtonTitle);
bundle->GetStringFromName("actionButton.label", actionButtonTitle);
if (!hostPort.IsEmpty()) {
AutoTArray<nsString, 1> formatStrings = {hostPort};
bundle->FormatStringFromName("webActions.disableForOrigin.label", formatStrings,
disableButtonTitle);
bundle->FormatStringFromName("webActions.disableForOrigin.label",
formatStrings, disableButtonTitle);
}
bundle->GetStringFromName("webActions.settings.label", settingsButtonTitle);
@ -288,15 +303,20 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
// Notification Center preferences, and doesn't support the alternate
// action menu.
if ([notification respondsToSelector:@selector(set_showsButtons:)] &&
[notification respondsToSelector:@selector(set_alwaysShowAlternateActionMenu:)] &&
[notification respondsToSelector:@selector(set_alternateActionButtonTitles:)]) {
[notification
respondsToSelector:@selector(set_alwaysShowAlternateActionMenu:)] &&
[notification
respondsToSelector:@selector(set_alternateActionButtonTitles:)]) {
notification.hasActionButton = YES;
notification.actionButtonTitle = nsCocoaUtils::ToNSString(actionButtonTitle);
notification.actionButtonTitle =
nsCocoaUtils::ToNSString(actionButtonTitle);
[(NSObject*)notification setValue:@(YES) forKey:@"_showsButtons"];
[(NSObject*)notification setValue:@(YES) forKey:@"_alwaysShowAlternateActionMenu"];
[(NSObject*)notification setValue:@(YES)
forKey:@"_alwaysShowAlternateActionMenu"];
[(NSObject*)notification setValue:@[
nsCocoaUtils::ToNSString(disableButtonTitle), nsCocoaUtils::ToNSString(settingsButtonTitle)
nsCocoaUtils::ToNSString(disableButtonTitle),
nsCocoaUtils::ToNSString(settingsButtonTitle)
]
forKey:@"_alternateActionButtonTitles"];
}
@ -315,19 +335,22 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
if (!alertName) {
return NS_ERROR_FAILURE;
}
notification.userInfo =
[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:alertName, nil]
forKeys:[NSArray arrayWithObjects:@"name", nil]];
notification.userInfo = [NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:alertName, nil]
forKeys:[NSArray arrayWithObjects:@"name", nil]];
nsAutoString cookie;
rv = aAlert->GetCookie(cookie);
NS_ENSURE_SUCCESS(rv, rv);
OSXNotificationInfo* osxni = new OSXNotificationInfo(alertName, aAlertListener, cookie);
OSXNotificationInfo* osxni =
new OSXNotificationInfo(alertName, aAlertListener, cookie);
// Show the favicon if supported on this version of OS X.
if (aIconSize > 0 && [notification respondsToSelector:@selector(set_identityImage:)] &&
[notification respondsToSelector:@selector(set_identityImageHasBorder:)]) {
if (aIconSize > 0 &&
[notification respondsToSelector:@selector(set_identityImage:)] &&
[notification
respondsToSelector:@selector(set_identityImageHasBorder:)]) {
NSData* iconData = [NSData dataWithBytes:aIconData length:aIconSize];
NSImage* icon = [[[NSImage alloc] initWithData:iconData] autorelease];
@ -339,8 +362,8 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
rv = aAlert->GetInPrivateBrowsing(&inPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
// Show the notification without waiting for an image if there is no icon URL or
// notification icons are not supported on this version of OS X.
// Show the notification without waiting for an image if there is no icon URL
// or notification icons are not supported on this version of OS X.
if (![unClass instancesRespondToSelector:@selector(setContentImage:)]) {
CloseAlertCocoaString(alertName);
mActiveAlerts.AppendElement(osxni);
@ -353,7 +376,8 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
mPendingAlerts.AppendElement(osxni);
osxni->mPendingNotification = notification;
// Wait six seconds for the image to load.
rv = aAlert->LoadImage(6000, this, osxni, getter_AddRefs(osxni->mIconRequest));
rv = aAlert->LoadImage(6000, this, osxni,
getter_AddRefs(osxni->mIconRequest));
if (NS_WARN_IF(NS_FAILED(rv))) {
ShowPendingNotification(osxni);
}
@ -365,7 +389,8 @@ OSXNotificationCenter::ShowAlertWithIconData(nsIAlertNotification* aAlert,
}
NS_IMETHODIMP
OSXNotificationCenter::CloseAlert(const nsAString& aAlertName, bool aContextClosed) {
OSXNotificationCenter::CloseAlert(const nsAString& aAlertName,
bool aContextClosed) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSString* alertName = nsCocoaUtils::ToNSString(aAlertName);
@ -396,7 +421,8 @@ void OSXNotificationCenter::CloseAlertCocoaString(NSString* aAlertName) {
OSXNotificationInfo* osxni = mActiveAlerts[i];
if ([aAlertName isEqualToString:osxni->mName]) {
if (osxni->mObserver) {
osxni->mObserver->Observe(nullptr, "alertfinished", osxni->mCookie.get());
osxni->mObserver->Observe(nullptr, "alertfinished",
osxni->mCookie.get());
}
if (osxni->mIconRequest) {
osxni->mIconRequest->Cancel(NS_BINDING_ABORTED);
@ -410,9 +436,9 @@ void OSXNotificationCenter::CloseAlertCocoaString(NSString* aAlertName) {
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
void OSXNotificationCenter::OnActivate(NSString* aAlertName,
NSUserNotificationActivationType aActivationType,
unsigned long long aAdditionalActionIndex) {
void OSXNotificationCenter::OnActivate(
NSString* aAlertName, NSUserNotificationActivationType aActivationType,
unsigned long long aAdditionalActionIndex) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!aAlertName) {
@ -428,18 +454,22 @@ void OSXNotificationCenter::OnActivate(NSString* aAlertName,
case NSUserNotificationActivationTypeActionButtonClicked:
switch (aAdditionalActionIndex) {
case OSXNotificationActionDisable:
osxni->mObserver->Observe(nullptr, "alertdisablecallback", osxni->mCookie.get());
osxni->mObserver->Observe(nullptr, "alertdisablecallback",
osxni->mCookie.get());
break;
case OSXNotificationActionSettings:
osxni->mObserver->Observe(nullptr, "alertsettingscallback", osxni->mCookie.get());
osxni->mObserver->Observe(nullptr, "alertsettingscallback",
osxni->mCookie.get());
break;
default:
NS_WARNING("Unknown NSUserNotification additional action clicked");
NS_WARNING(
"Unknown NSUserNotification additional action clicked");
break;
}
break;
default:
osxni->mObserver->Observe(nullptr, "alertclickcallback", osxni->mCookie.get());
osxni->mObserver->Observe(nullptr, "alertclickcallback",
osxni->mCookie.get());
break;
}
}
@ -450,7 +480,8 @@ void OSXNotificationCenter::OnActivate(NSString* aAlertName,
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
void OSXNotificationCenter::ShowPendingNotification(OSXNotificationInfo* osxni) {
void OSXNotificationCenter::ShowPendingNotification(
OSXNotificationInfo* osxni) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (osxni->mIconRequest) {
@ -496,7 +527,8 @@ OSXNotificationCenter::OnImageMissing(nsISupports* aUserData) {
}
NS_IMETHODIMP
OSXNotificationCenter::OnImageReady(nsISupports* aUserData, imgIRequest* aRequest) {
OSXNotificationCenter::OnImageReady(nsISupports* aUserData,
imgIRequest* aRequest) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsCOMPtr<imgIContainer> image;
@ -511,9 +543,10 @@ OSXNotificationCenter::OnImageReady(nsISupports* aUserData, imgIRequest* aReques
}
NSImage* cocoaImage = nil;
// TODO: Pass pres context / ComputedStyle here to support context paint properties
nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(image, imgIContainer::FRAME_FIRST,
nullptr, nullptr, &cocoaImage);
// TODO: Pass pres context / ComputedStyle here to support context paint
// properties
nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
image, imgIContainer::FRAME_FIRST, nullptr, nullptr, &cocoaImage);
(osxni->mPendingNotification).contentImage = cocoaImage;
[cocoaImage release];
ShowPendingNotification(osxni);
@ -525,7 +558,9 @@ OSXNotificationCenter::OnImageReady(nsISupports* aUserData, imgIRequest* aReques
// nsIAlertsDoNotDisturb
NS_IMETHODIMP
OSXNotificationCenter::GetManualDoNotDisturb(bool* aRetVal) { return NS_ERROR_NOT_IMPLEMENTED; }
OSXNotificationCenter::GetManualDoNotDisturb(bool* aRetVal) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
OSXNotificationCenter::SetManualDoNotDisturb(bool aDoNotDisturb) {

Просмотреть файл

@ -79,19 +79,20 @@ ScreenHelperCocoa::~ScreenHelperCocoa() {
static already_AddRefed<Screen> MakeScreen(NSScreen* aScreen) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
DesktopToLayoutDeviceScale contentsScaleFactor(nsCocoaUtils::GetBackingScaleFactor(aScreen));
DesktopToLayoutDeviceScale contentsScaleFactor(
nsCocoaUtils::GetBackingScaleFactor(aScreen));
CSSToLayoutDeviceScale defaultCssScaleFactor(contentsScaleFactor.scale);
NSRect frame = [aScreen frame];
LayoutDeviceIntRect rect =
nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, contentsScaleFactor.scale);
LayoutDeviceIntRect rect = nsCocoaUtils::CocoaRectToGeckoRectDevPix(
frame, contentsScaleFactor.scale);
frame = [aScreen visibleFrame];
LayoutDeviceIntRect availRect =
nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, contentsScaleFactor.scale);
LayoutDeviceIntRect availRect = nsCocoaUtils::CocoaRectToGeckoRectDevPix(
frame, contentsScaleFactor.scale);
// aScreen may be capable of displaying multiple pixel depths, for example by
// transitioning to an HDR-capable depth when required by a window displayed on
// the screen. We want to note the maximum capabilities of the screen, so we use
// the largest depth it offers.
// transitioning to an HDR-capable depth when required by a window displayed
// on the screen. We want to note the maximum capabilities of the screen, so
// we use the largest depth it offers.
uint32_t pixelDepth = 0;
const NSWindowDepth* depths = [aScreen supportedWindowDepths];
for (size_t d = 0; NSWindowDepth depth = depths[d]; d++) {
@ -116,16 +117,17 @@ static already_AddRefed<Screen> MakeScreen(NSScreen* aScreen) {
dpi = rect.height / (heightMM / MM_PER_INCH_FLOAT);
}
MOZ_LOG(sScreenLog, LogLevel::Debug,
("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect.x, rect.y, rect.width,
rect.height, availRect.x, availRect.y, availRect.width, availRect.height, pixelDepth,
contentsScaleFactor.scale, defaultCssScaleFactor.scale, dpi));
("New screen [%d %d %d %d (%d %d %d %d) %d %f %f %f]", rect.x, rect.y,
rect.width, rect.height, availRect.x, availRect.y, availRect.width,
availRect.height, pixelDepth, contentsScaleFactor.scale,
defaultCssScaleFactor.scale, dpi));
// Getting the refresh rate is a little hard on OS X. We could use
// CVDisplayLinkGetNominalOutputVideoRefreshPeriod, but that's a little
// involved. Ideally we could query it from vsync. For now, we leave it out.
RefPtr<Screen> screen =
new Screen(rect, availRect, pixelDepth, pixelDepth, 0, contentsScaleFactor,
defaultCssScaleFactor, dpi, Screen::IsPseudoDisplay::No);
RefPtr<Screen> screen = new Screen(rect, availRect, pixelDepth, pixelDepth, 0,
contentsScaleFactor, defaultCssScaleFactor,
dpi, Screen::IsPseudoDisplay::No);
return screen.forget();
NS_OBJC_END_TRY_BLOCK_RETURN(nullptr);
@ -164,7 +166,8 @@ NSScreen* ScreenHelperCocoa::CocoaScreenForScreen(nsIScreen* aScreen) {
aScreen->GetRect(&rect.x, &rect.y, &rect.width, &rect.height);
aScreen->GetContentsScaleFactor(&scale);
NSRect frame = [screen frame];
LayoutDeviceIntRect frameRect = nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, scale);
LayoutDeviceIntRect frameRect =
nsCocoaUtils::CocoaRectToGeckoRectDevPix(frame, scale);
if (rect == frameRect) {
return screen;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -18,7 +18,8 @@
namespace mozilla::widget {
auto TextRecognition::DoFindText(gfx::DataSourceSurface& aSurface,
const nsTArray<nsCString>& aLanguages) -> RefPtr<NativePromise> {
const nsTArray<nsCString>& aLanguages)
-> RefPtr<NativePromise> {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK
// TODO - Is this the most efficient path? Maybe we can write a new
@ -26,7 +27,8 @@ auto TextRecognition::DoFindText(gfx::DataSourceSurface& aSurface,
CGImageRef imageRef = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(&aSurface, &imageRef);
if (NS_FAILED(rv) || !imageRef) {
return NativePromise::CreateAndReject("Failed to create CGImage"_ns, __func__);
return NativePromise::CreateAndReject("Failed to create CGImage"_ns,
__func__);
}
auto promise = MakeRefPtr<NativePromise::Private>(__func__);
@ -48,47 +50,63 @@ auto TextRecognition::DoFindText(gfx::DataSourceSurface& aSurface,
dom::TextRecognitionResult result;
dom::TextRecognitionResult* pResult = &result;
// Define the request to use, which also handles the result. It will be run below
// directly in this thread. After creating this request.
VNRecognizeTextRequest* textRecognitionRequest = [[VNRecognizeTextRequest alloc]
initWithCompletionHandler:^(VNRequest* _Nonnull request, NSError* _Nullable error) {
NSArray<VNRecognizedTextObservation*>* observations = request.results;
// Define the request to use, which also handles the result. It will
// be run below directly in this thread. After creating this
// request.
VNRecognizeTextRequest* textRecognitionRequest =
[[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(
VNRequest* _Nonnull request,
NSError* _Nullable error) {
NSArray<VNRecognizedTextObservation*>* observations =
request.results;
[observations
enumerateObjectsUsingBlock:^(VNRecognizedTextObservation* _Nonnull obj,
NSUInteger idx, BOOL* _Nonnull stop) {
// Requests the n top candidates for a recognized text string.
VNRecognizedText* recognizedText = [obj topCandidates:1].firstObject;
[observations enumerateObjectsUsingBlock:^(
VNRecognizedTextObservation* _Nonnull obj,
NSUInteger idx, BOOL* _Nonnull stop) {
// Requests the n top candidates for a recognized text
// string.
VNRecognizedText* recognizedText =
[obj topCandidates:1].firstObject;
// https://developer.apple.com/documentation/vision/vnrecognizedtext?language=objc
auto& quad = *pResult->quads().AppendElement();
CopyCocoaStringToXPCOMString(recognizedText.string, quad.string());
quad.confidence() = recognizedText.confidence;
// https://developer.apple.com/documentation/vision/vnrecognizedtext?language=objc
auto& quad = *pResult->quads().AppendElement();
CopyCocoaStringToXPCOMString(recognizedText.string,
quad.string());
quad.confidence() = recognizedText.confidence;
auto ToImagePoint = [](CGPoint aPoint) -> ImagePoint {
return {static_cast<float>(aPoint.x), static_cast<float>(aPoint.y)};
};
*quad.points().AppendElement() = ToImagePoint(obj.bottomLeft);
*quad.points().AppendElement() = ToImagePoint(obj.topLeft);
*quad.points().AppendElement() = ToImagePoint(obj.topRight);
*quad.points().AppendElement() = ToImagePoint(obj.bottomRight);
}];
auto ToImagePoint = [](CGPoint aPoint) -> ImagePoint {
return {static_cast<float>(aPoint.x),
static_cast<float>(aPoint.y)};
};
*quad.points().AppendElement() =
ToImagePoint(obj.bottomLeft);
*quad.points().AppendElement() = ToImagePoint(obj.topLeft);
*quad.points().AppendElement() = ToImagePoint(obj.topRight);
*quad.points().AppendElement() =
ToImagePoint(obj.bottomRight);
}];
}];
textRecognitionRequest.recognitionLevel = VNRequestTextRecognitionLevelAccurate;
textRecognitionRequest.recognitionLevel =
VNRequestTextRecognitionLevelAccurate;
textRecognitionRequest.recognitionLanguages = recognitionLanguages;
textRecognitionRequest.usesLanguageCorrection = true;
// Send out the request. This blocks execution of this thread with an expensive
// CPU call.
// Send out the request. This blocks execution of this thread with
// an expensive CPU call.
NSError* error = nil;
VNImageRequestHandler* requestHandler =
[[[VNImageRequestHandler alloc] initWithCGImage:imageRef options:@{}] autorelease];
[[[VNImageRequestHandler alloc] initWithCGImage:imageRef
options:@{}]
autorelease];
[requestHandler performRequests:@[ textRecognitionRequest ] error:&error];
[requestHandler performRequests:@[ textRecognitionRequest ]
error:&error];
if (error != nil) {
promise->Reject(
nsPrintfCString("Failed to perform text recognition request (%ld)\n", error.code),
nsPrintfCString(
"Failed to perform text recognition request (%ld)\n",
error.code),
__func__);
} else {
promise->Resolve(std::move(result), __func__);

Просмотреть файл

@ -16,27 +16,29 @@ using namespace mozilla;
@interface MOZVibrantView : NSVisualEffectView {
VibrancyType mType;
}
- (instancetype)initWithFrame:(NSRect)aRect vibrancyType:(VibrancyType)aVibrancyType;
- (instancetype)initWithFrame:(NSRect)aRect
vibrancyType:(VibrancyType)aVibrancyType;
@end
@interface MOZVibrantLeafView : MOZVibrantView
@end
static NSVisualEffectState VisualEffectStateForVibrancyType(VibrancyType aType) {
static NSVisualEffectState VisualEffectStateForVibrancyType(
VibrancyType aType) {
switch (aType) {
case VibrancyType::TOOLTIP:
case VibrancyType::MENU:
case VibrancyType::HIGHLIGHTED_MENUITEM:
// Tooltip and menu windows are never "key", so we need to tell the vibrancy effect to look
// active regardless of window state.
// Tooltip and menu windows are never "key", so we need to tell the
// vibrancy effect to look active regardless of window state.
return NSVisualEffectStateActive;
default:
return NSVisualEffectStateFollowsWindowActiveState;
}
}
static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(VibrancyType aType,
BOOL* aOutIsEmphasized) {
static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(
VibrancyType aType, BOOL* aOutIsEmphasized) {
switch (aType) {
case VibrancyType::TOOLTIP:
return (NSVisualEffectMaterial)NSVisualEffectMaterialToolTip;
@ -90,8 +92,8 @@ static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(VibrancyType a
@end
bool VibrancyManager::UpdateVibrantRegion(VibrancyType aType,
const LayoutDeviceIntRegion& aRegion) {
bool VibrancyManager::UpdateVibrantRegion(
VibrancyType aType, const LayoutDeviceIntRegion& aRegion) {
if (aRegion.IsEmpty()) {
return mVibrantRegions.Remove(uint32_t(aType));
}
@ -109,7 +111,10 @@ LayoutDeviceIntRegion VibrancyManager::GetUnionOfVibrantRegions() const {
return result;
}
/* static */ NSView* VibrancyManager::CreateEffectView(VibrancyType aType, BOOL aIsContainer) {
return aIsContainer ? [[MOZVibrantView alloc] initWithFrame:NSZeroRect vibrancyType:aType]
: [[MOZVibrantLeafView alloc] initWithFrame:NSZeroRect vibrancyType:aType];
/* static */ NSView* VibrancyManager::CreateEffectView(VibrancyType aType,
BOOL aIsContainer) {
return aIsContainer ? [[MOZVibrantView alloc] initWithFrame:NSZeroRect
vibrancyType:aType]
: [[MOZVibrantLeafView alloc] initWithFrame:NSZeroRect
vibrancyType:aType];
}

Просмотреть файл

@ -18,7 +18,8 @@ ViewRegion::~ViewRegion() {
}
bool ViewRegion::UpdateRegion(const LayoutDeviceIntRegion& aRegion,
const nsChildView& aCoordinateConverter, NSView* aContainerView,
const nsChildView& aCoordinateConverter,
NSView* aContainerView,
NSView* (^aViewCreationCallback)()) {
if (mRegion == aRegion) {
return false;
@ -33,7 +34,8 @@ bool ViewRegion::UpdateRegion(const LayoutDeviceIntRegion& aRegion,
// The mViews array is now empty.
size_t i = 0;
for (auto iter = aRegion.RectIter(); !iter.Done() || i < viewsToRecycle.Length(); i++) {
for (auto iter = aRegion.RectIter();
!iter.Done() || i < viewsToRecycle.Length(); i++) {
if (!iter.Done()) {
NSView* view = nil;
NSRect rect = aCoordinateConverter.DevPixelsToCocoaPoints(iter.Get());

Просмотреть файл

@ -57,7 +57,8 @@
using namespace mozilla;
using namespace mozilla::widget;
#define WAKE_LOCK_LOG(...) MOZ_LOG(gMacWakeLockLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#define WAKE_LOCK_LOG(...) \
MOZ_LOG(gMacWakeLockLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
static mozilla::LazyLogModule gMacWakeLockLog("MacWakeLock");
// A wake lock listener that disables screen saver when requested by
@ -74,24 +75,30 @@ class MacWakeLockListener final : public nsIDOMMozWakeLockListener {
IOPMAssertionID mAssertionNoDisplaySleepID = kIOPMNullAssertionID;
IOPMAssertionID mAssertionNoIdleSleepID = kIOPMNullAssertionID;
NS_IMETHOD Callback(const nsAString& aTopic, const nsAString& aState) override {
NS_IMETHOD Callback(const nsAString& aTopic,
const nsAString& aState) override {
if (!aTopic.EqualsASCII("screen") && !aTopic.EqualsASCII("audio-playing") &&
!aTopic.EqualsASCII("video-playing")) {
return NS_OK;
}
// we should still hold the lock for background audio.
if (aTopic.EqualsASCII("audio-playing") && aState.EqualsASCII("locked-background")) {
if (aTopic.EqualsASCII("audio-playing") &&
aState.EqualsASCII("locked-background")) {
WAKE_LOCK_LOG("keep audio playing even in background");
return NS_OK;
}
bool shouldKeepDisplayOn = aTopic.EqualsASCII("screen") || aTopic.EqualsASCII("video-playing");
CFStringRef assertionType =
shouldKeepDisplayOn ? kIOPMAssertionTypeNoDisplaySleep : kIOPMAssertionTypeNoIdleSleep;
IOPMAssertionID& assertionId =
shouldKeepDisplayOn ? mAssertionNoDisplaySleepID : mAssertionNoIdleSleepID;
WAKE_LOCK_LOG("topic=%s, state=%s, shouldKeepDisplayOn=%d", NS_ConvertUTF16toUTF8(aTopic).get(),
bool shouldKeepDisplayOn =
aTopic.EqualsASCII("screen") || aTopic.EqualsASCII("video-playing");
CFStringRef assertionType = shouldKeepDisplayOn
? kIOPMAssertionTypeNoDisplaySleep
: kIOPMAssertionTypeNoIdleSleep;
IOPMAssertionID& assertionId = shouldKeepDisplayOn
? mAssertionNoDisplaySleepID
: mAssertionNoIdleSleepID;
WAKE_LOCK_LOG("topic=%s, state=%s, shouldKeepDisplayOn=%d",
NS_ConvertUTF16toUTF8(aTopic).get(),
NS_ConvertUTF16toUTF8(aState).get(), shouldKeepDisplayOn);
// Note the wake lock code ensures that we're not sent duplicate
@ -103,9 +110,10 @@ class MacWakeLockListener final : public nsIDOMMozWakeLockListener {
}
// Prevent screen saver.
CFStringRef cf_topic = ::CFStringCreateWithCharacters(
kCFAllocatorDefault, reinterpret_cast<const UniChar*>(aTopic.Data()), aTopic.Length());
IOReturn success = ::IOPMAssertionCreateWithName(assertionType, kIOPMAssertionLevelOn,
cf_topic, &assertionId);
kCFAllocatorDefault, reinterpret_cast<const UniChar*>(aTopic.Data()),
aTopic.Length());
IOReturn success = ::IOPMAssertionCreateWithName(
assertionType, kIOPMAssertionLevelOn, cf_topic, &assertionId);
CFRelease(cf_topic);
if (success != kIOReturnSuccess) {
WAKE_LOCK_LOG("failed to disable screensaver");
@ -133,19 +141,21 @@ static bool gAppShellMethodsSwizzled = false;
void OnUncaughtException(NSException* aException) {
nsObjCExceptionLog(aException);
MOZ_CRASH("Uncaught Objective C exception from NSSetUncaughtExceptionHandler");
MOZ_CRASH(
"Uncaught Objective C exception from NSSetUncaughtExceptionHandler");
}
@implementation GeckoNSApplication
// Load is called very early during startup, when the Objective C runtime loads this class.
// Load is called very early during startup, when the Objective C runtime loads
// this class.
+ (void)load {
NSSetUncaughtExceptionHandler(OnUncaughtException);
}
// This method is called from NSDefaultTopLevelErrorHandler, which is invoked when an Objective C
// exception propagates up into the native event loop. It is possible that it is also called in
// other cases.
// This method is called from NSDefaultTopLevelErrorHandler, which is invoked
// when an Objective C exception propagates up into the native event loop. It is
// possible that it is also called in other cases.
- (void)reportException:(NSException*)aException {
if (ShouldIgnoreObjCException(aException)) {
return;
@ -154,14 +164,16 @@ void OnUncaughtException(NSException* aException) {
nsObjCExceptionLog(aException);
#ifdef NIGHTLY_BUILD
MOZ_CRASH("Uncaught Objective C exception from -[GeckoNSApplication reportException:]");
MOZ_CRASH("Uncaught Objective C exception from -[GeckoNSApplication "
"reportException:]");
#endif
}
- (void)sendEvent:(NSEvent*)anEvent {
mozilla::BackgroundHangMonitor().NotifyActivity();
if ([anEvent type] == NSEventTypeApplicationDefined && [anEvent subtype] == kEventSubtypeTrace) {
if ([anEvent type] == NSEventTypeApplicationDefined &&
[anEvent subtype] == kEventSubtypeTrace) {
mozilla::SignalTracerThread();
return;
}
@ -208,7 +220,8 @@ void OnUncaughtException(NSException* aException) {
NS_IMETHODIMP
nsAppShell::ResumeNative(void) {
nsresult retval = nsBaseAppShell::ResumeNative();
if (NS_SUCCEEDED(retval) && (mSuspendNativeCount == 0) && mSkippedNativeCallback) {
if (NS_SUCCEEDED(retval) && (mSuspendNativeCount == 0) &&
mSkippedNativeCallback) {
mSkippedNativeCallback = false;
ScheduleNativeEventCallback();
}
@ -243,11 +256,13 @@ nsAppShell::~nsAppShell() {
if (mCFRunLoop) {
if (mCFRunLoopSource) {
::CFRunLoopRemoveSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
::CFRunLoopRemoveSource(mCFRunLoop, mCFRunLoopSource,
kCFRunLoopCommonModes);
::CFRelease(mCFRunLoopSource);
}
if (mCFRunLoopObserver) {
::CFRunLoopRemoveObserver(mCFRunLoop, mCFRunLoopObserver, kCFRunLoopCommonModes);
::CFRunLoopRemoveObserver(mCFRunLoop, mCFRunLoopObserver,
kCFRunLoopCommonModes);
::CFRelease(mCFRunLoopObserver);
}
::CFRelease(mCFRunLoop);
@ -274,7 +289,8 @@ static void AddScreenWakeLockListener() {
sWakeLockListener = new MacWakeLockListener();
sPowerManagerService->AddWakeLockListener(sWakeLockListener);
} else {
NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!");
NS_WARNING(
"Failed to retrieve PowerManagerService, wakelocks will be broken!");
}
}
@ -288,8 +304,8 @@ static void RemoveScreenWakeLockListener() {
}
}
void RunLoopObserverCallback(CFRunLoopObserverRef aObserver, CFRunLoopActivity aActivity,
void* aInfo) {
void RunLoopObserverCallback(CFRunLoopObserverRef aObserver,
CFRunLoopActivity aActivity, void* aInfo) {
static_cast<nsAppShell*>(aInfo)->OnRunLoopActivityChanged(aActivity);
}
@ -298,30 +314,34 @@ void nsAppShell::OnRunLoopActivityChanged(CFRunLoopActivity aActivity) {
mozilla::BackgroundHangMonitor().NotifyWait();
}
// When the event loop is in its waiting state, we would like the profiler to know that the thread
// is idle. The usual way to notify the profiler of idleness would be to place a profiler label
// frame with the IDLE category on the stack, for the duration of the function that does the
// waiting. However, since macOS uses an event loop model where "the event loop calls you", we do
// not control the function that does the waiting; the waiting happens inside CFRunLoop code.
// Instead, the run loop notifies us when it enters and exits the waiting state, by calling this
// function.
// So we do not have a function under our control that stays on the stack for the duration of the
// wait. So, rather than putting an AutoProfilerLabel on the stack, we will manually push and pop
// the label frame here.
// The location in the stack where this label frame is inserted is somewhat arbitrary. In
// practice, the label frame will be at the very tip of the stack, looking like it's "inside" the
// When the event loop is in its waiting state, we would like the profiler to
// know that the thread is idle. The usual way to notify the profiler of
// idleness would be to place a profiler label frame with the IDLE category on
// the stack, for the duration of the function that does the waiting. However,
// since macOS uses an event loop model where "the event loop calls you", we
// do not control the function that does the waiting; the waiting happens
// inside CFRunLoop code. Instead, the run loop notifies us when it enters and
// exits the waiting state, by calling this function. So we do not have a
// function under our control that stays on the stack for the duration of the
// wait. So, rather than putting an AutoProfilerLabel on the stack, we will
// manually push and pop the label frame here. The location in the stack where
// this label frame is inserted is somewhat arbitrary. In practice, the label
// frame will be at the very tip of the stack, looking like it's "inside" the
// mach_msg_trap wait function.
if (aActivity == kCFRunLoopBeforeWaiting) {
using ThreadRegistration = mozilla::profiler::ThreadRegistration;
ThreadRegistration::WithOnThreadRef([&](ThreadRegistration::OnThreadRef aOnThreadRef) {
ProfilingStack& profilingStack =
aOnThreadRef.UnlockedConstReaderAndAtomicRWRef().ProfilingStackRef();
mProfilingStackWhileWaiting = &profilingStack;
uint8_t variableOnStack = 0;
profilingStack.pushLabelFrame("Native event loop idle", nullptr, &variableOnStack,
JS::ProfilingCategoryPair::IDLE, 0);
profiler_thread_sleep();
});
ThreadRegistration::WithOnThreadRef(
[&](ThreadRegistration::OnThreadRef aOnThreadRef) {
ProfilingStack& profilingStack =
aOnThreadRef.UnlockedConstReaderAndAtomicRWRef()
.ProfilingStackRef();
mProfilingStackWhileWaiting = &profilingStack;
uint8_t variableOnStack = 0;
profilingStack.pushLabelFrame("Native event loop idle", nullptr,
&variableOnStack,
JS::ProfilingCategoryPair::IDLE, 0);
profiler_thread_sleep();
});
} else {
if (mProfilingStackWhileWaiting) {
mProfilingStackWhileWaiting->pop();
@ -356,8 +376,9 @@ nsresult nsAppShell::Init() {
mAutoreleasePools = ::CFArrayCreateMutable(nullptr, 0, nullptr);
NS_ENSURE_STATE(mAutoreleasePools);
bool isNSApplicationProcessType = (XRE_GetProcessType() != GeckoProcessType_RDD) &&
(XRE_GetProcessType() != GeckoProcessType_Socket);
bool isNSApplicationProcessType =
(XRE_GetProcessType() != GeckoProcessType_RDD) &&
(XRE_GetProcessType() != GeckoProcessType_Socket);
if (isNSApplicationProcessType) {
// This call initializes NSApplication unless:
@ -391,14 +412,15 @@ nsresult nsAppShell::Init() {
::CFRunLoopAddSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
// Add a CFRunLoopObserver so that the profiler can be notified when we enter and exit the waiting
// state.
// Add a CFRunLoopObserver so that the profiler can be notified when we enter
// and exit the waiting state.
CFRunLoopObserverContext observerContext;
PodZero(&observerContext);
observerContext.info = this;
mCFRunLoopObserver = ::CFRunLoopObserverCreate(
kCFAllocatorDefault, kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting | kCFRunLoopExit, true,
kCFAllocatorDefault,
kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting | kCFRunLoopExit, true,
0, RunLoopObserverCallback, &observerContext);
NS_ENSURE_STATE(mCFRunLoopObserver);
@ -491,9 +513,10 @@ void nsAppShell::ProcessGeckoEvents(void* aInfo) {
// DummyEvent inserted by nsBaseAppShell::OnProcessNextEvent. This second
// event will cause the second call to AcquireFirstMatchingEventInQueue in
// nsAppShell::ProcessNextNativeEvent to return true. Which makes
// nsBaseAppShell::OnProcessNextEvent call nsAppShell::ProcessNextNativeEvent
// again during which it will loop until it sleeps because ProcessGeckoEvents()
// won't be called for the DummyEvent.
// nsBaseAppShell::OnProcessNextEvent call
// nsAppShell::ProcessNextNativeEvent again during which it will loop until
// it sleeps because ProcessGeckoEvents() won't be called for the
// DummyEvent.
//
// This is not a good approach and we should fix things up so that only
// one postEvent is needed.
@ -551,8 +574,8 @@ void nsAppShell::ProcessGeckoEvents(void* aInfo) {
if (self->mTerminated) {
int32_t releaseCount = 0;
if (self->mNativeEventScheduledDepth > self->mNativeEventCallbackDepth) {
releaseCount =
PR_ATOMIC_SET(&self->mNativeEventScheduledDepth, self->mNativeEventCallbackDepth);
releaseCount = PR_ATOMIC_SET(&self->mNativeEventScheduledDepth,
self->mNativeEventCallbackDepth);
}
while (releaseCount-- > self->mNativeEventCallbackDepth) self->Release();
} else {
@ -651,10 +674,10 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
if (mTerminated) return false;
// Do not call -[NSApplication nextEventMatchingMask:...] when we're trying to close a native
// menu. Doing so could confuse the NSMenu's closing mechanism. Instead, we try to unwind the
// stack as quickly as possible and return to the parent event loop. At that point, native events
// will be processed.
// Do not call -[NSApplication nextEventMatchingMask:...] when we're trying to
// close a native menu. Doing so could confuse the NSMenu's closing mechanism.
// Instead, we try to unwind the stack as quickly as possible and return to
// the parent event loop. At that point, native events will be processed.
if (MOZMenuOpeningCoordinator.needToUnwindForMenuClosing) {
return false;
}
@ -700,12 +723,13 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
}
} else {
// In at least 10.15, AcquireFirstMatchingEventInQueue will move 1
// CGEvent from the CGEvent queue into the Carbon event queue. Unfortunately,
// once an event has been moved to the Carbon event queue it's no longer a
// candidate for coalescing. This means that even if we don't remove the
// event from the queue, just calling AcquireFirstMatchingEventInQueue can
// cause behaviour change. Prior to bug 1690687 landing, the event that we got
// from AcquireFirstMatchingEventInQueue was often our own ApplicationDefined
// CGEvent from the CGEvent queue into the Carbon event queue.
// Unfortunately, once an event has been moved to the Carbon event queue
// it's no longer a candidate for coalescing. This means that even if we
// don't remove the event from the queue, just calling
// AcquireFirstMatchingEventInQueue can cause behaviour change. Prior to
// bug 1690687 landing, the event that we got from
// AcquireFirstMatchingEventInQueue was often our own ApplicationDefined
// event. However, once we stopped posting that event on every Gecko
// event we're much more likely to get a CGEvent. When we have a high
// amount of load on the main thread, we end up alternating between Gecko
@ -719,8 +743,8 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
// AcquireFirstMatchingEventInQueue() doesn't spin the (native) event
// loop, though it does queue up any newly available events from the
// window server.
EventRef currentEvent =
AcquireFirstMatchingEventInQueue(currentEventQueue, 0, NULL, kEventQueueOptionsNone);
EventRef currentEvent = AcquireFirstMatchingEventInQueue(
currentEventQueue, 0, NULL, kEventQueueOptionsNone);
if (!currentEvent) {
continue;
}
@ -729,7 +753,8 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
UInt32 eventClass = GetEventClass(currentEvent);
bool osCocoaEvent =
((eventClass == 'appl') || (eventClass == kEventClassAppleEvent) ||
((eventClass == 'cgs ') && (eventKind != NSEventTypeApplicationDefined)));
((eventClass == 'cgs ') &&
(eventKind != NSEventTypeApplicationDefined)));
// If attrs is kEventAttributeUserEvent or kEventAttributeMonitored
// (i.e. a user input event), we shouldn't process it here while
// aMayWait is false. Likewise if currentEvent will eventually be
@ -761,8 +786,9 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
} while (mRunningEventLoop);
if (eventProcessed) {
moreEvents = (AcquireFirstMatchingEventInQueue(currentEventQueue, 0, NULL,
kEventQueueOptionsNone) != NULL);
moreEvents =
(AcquireFirstMatchingEventInQueue(currentEventQueue, 0, NULL,
kEventQueueOptionsNone) != NULL);
}
mRunningEventLoop = wasRunningEventLoop;
@ -790,7 +816,9 @@ bool nsAppShell::ProcessNextNativeEvent(bool aMayWait) {
// (Ventura) than on other versions of macOS. So we only use this hack on
// macOS 13 and up.
static void PinSidecarCoreTextCStringSections() {
if (!dlopen("/System/Library/PrivateFrameworks/SidecarCore.framework/SidecarCore", RTLD_LAZY)) {
if (!dlopen(
"/System/Library/PrivateFrameworks/SidecarCore.framework/SidecarCore",
RTLD_LAZY)) {
return;
}
@ -798,7 +826,8 @@ static void PinSidecarCoreTextCStringSections() {
// normally runs automatically on the first Cmd-key combination.
Class displayManagerClass = NSClassFromString(@"SidecarDisplayManager");
if ([displayManagerClass respondsToSelector:@selector(sharedManager)]) {
id sharedManager = [displayManagerClass performSelector:@selector(sharedManager)];
id sharedManager =
[displayManagerClass performSelector:@selector(sharedManager)];
if ([sharedManager respondsToSelector:@selector(devices)]) {
[sharedManager performSelector:@selector(devices)];
}
@ -877,7 +906,8 @@ nsAppShell::Exit(void) {
// [NSApp stop:], so we have to assume that one extra call to [NSApp stop:]
// will do the job.)
BOOL cocoaModal = [NSApp _isRunningModal];
NS_ASSERTION(!cocoaModal, "Don't call nsAppShell::Exit() from a modal event loop!");
NS_ASSERTION(!cocoaModal,
"Don't call nsAppShell::Exit() from a modal event loop!");
if (cocoaModal) [NSApp stop:nullptr];
[NSApp stop:nullptr];
@ -911,7 +941,8 @@ NS_IMETHODIMP
nsAppShell::OnProcessNextEvent(nsIThreadInternal* aThread, bool aMayWait) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NS_ASSERTION(mAutoreleasePools, "No stack on which to store autorelease pool");
NS_ASSERTION(mAutoreleasePools,
"No stack on which to store autorelease pool");
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
::CFArrayAppendValue(mAutoreleasePools, pool);
@ -929,15 +960,17 @@ nsAppShell::OnProcessNextEvent(nsIThreadInternal* aThread, bool aMayWait) {
//
// public
NS_IMETHODIMP
nsAppShell::AfterProcessNextEvent(nsIThreadInternal* aThread, bool aEventWasProcessed) {
nsAppShell::AfterProcessNextEvent(nsIThreadInternal* aThread,
bool aEventWasProcessed) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
NS_ASSERTION(mAutoreleasePools && count, "Processed an event, but there's no autorelease pool?");
NS_ASSERTION(mAutoreleasePools && count,
"Processed an event, but there's no autorelease pool?");
const NSAutoreleasePool* pool =
static_cast<const NSAutoreleasePool*>(::CFArrayGetValueAtIndex(mAutoreleasePools, count - 1));
const NSAutoreleasePool* pool = static_cast<const NSAutoreleasePool*>(
::CFArrayGetValueAtIndex(mAutoreleasePools, count - 1));
::CFArrayRemoveValueAtIndex(mAutoreleasePools, count - 1);
[pool release];
@ -952,11 +985,11 @@ void nsAppShell::InitMemoryPressureObserver() {
// values. Hence this may need to be augmented with polling of the memory
// pressure sysctls for lower latency reactions to OS memory pressure. This
// was also observed when using DISPATCH_QUEUE_PRIORITY_HIGH.
mMemoryPressureSource =
dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN |
DISPATCH_MEMORYPRESSURE_CRITICAL,
dispatch_get_main_queue());
mMemoryPressureSource = dispatch_source_create(
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN |
DISPATCH_MEMORYPRESSURE_CRITICAL,
dispatch_get_main_queue());
dispatch_source_set_event_handler(mMemoryPressureSource, ^{
dispatch_source_memorypressure_flags_t pressureLevel =
@ -971,7 +1004,8 @@ void nsAppShell::InitMemoryPressureObserver() {
nsAvailableMemoryWatcherBase::GetSingleton());
}
void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t aPressureLevel) {
void nsAppShell::OnMemoryPressureChanged(
dispatch_source_memorypressure_flags_t aPressureLevel) {
// The memory pressure dispatch source is created (above) with
// dispatch_get_main_queue() which always fires on the main thread.
MOZ_ASSERT(NS_IsMainThread());
@ -1008,18 +1042,21 @@ void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t
if ((self = [self init])) {
mAppShell = aAppShell;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(timezoneChanged:)
name:NSSystemTimeZoneDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:NSApp];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(timezoneChanged:)
name:NSSystemTimeZoneDidChangeNotification
object:nil];
}
return self;
@ -1061,12 +1098,14 @@ void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t
NSEvent* currentEvent = [NSApp currentEvent];
if (currentEvent) {
TextInputHandler::sLastModifierState =
[currentEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
[currentEvent modifierFlags] &
NSEventModifierFlagDeviceIndependentFlagsMask;
}
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService) {
observerService->NotifyObservers(nullptr, NS_WIDGET_MAC_APP_ACTIVATE_OBSERVER_TOPIC, nullptr);
observerService->NotifyObservers(
nullptr, NS_WIDGET_MAC_APP_ACTIVATE_OBSERVER_TOPIC, nullptr);
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
@ -1111,8 +1150,9 @@ void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t
// in XRE_Main(), which in particular means that ScopedXPCOMStartup's destructor
// and NS_ShutdownXPCOM() never get called.
- (void)nsAppShell_NSApplication_terminate:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter]
postNotificationName:NSApplicationWillTerminateNotification
object:NSApp];
}
@end

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -32,9 +32,10 @@ mozilla::StaticRefPtr<nsITransferable> nsClipboard::sSelectionCache;
int32_t nsClipboard::sSelectionCacheChangeCount = 0;
nsClipboard::nsClipboard()
: nsBaseClipboard(mozilla::dom::ClipboardCapabilities(false /* supportsSelectionClipboard */,
true /* supportsFindClipboard */,
true /* supportsSelectionCache */)) {}
: nsBaseClipboard(mozilla::dom::ClipboardCapabilities(
false /* supportsSelectionClipboard */,
true /* supportsFindClipboard */,
true /* supportsSelectionCache */)) {}
nsClipboard::~nsClipboard() { ClearSelectionCache(); }
@ -45,15 +46,16 @@ namespace {
// We separate this into its own function because after an @try, all local
// variables within that function get marked as volatile, and our C++ type
// system doesn't like volatile things.
static NSData* GetDataFromPasteboard(NSPasteboard* aPasteboard, NSString* aType) {
static NSData* GetDataFromPasteboard(NSPasteboard* aPasteboard,
NSString* aType) {
NSData* data = nil;
@try {
data = [aPasteboard dataForType:aType];
} @catch (NSException* e) {
NS_WARNING(
nsPrintfCString("Exception raised while getting data from the pasteboard: \"%s - %s\"",
[[e name] UTF8String], [[e reason] UTF8String])
.get());
NS_WARNING(nsPrintfCString("Exception raised while getting data from the "
"pasteboard: \"%s - %s\"",
[[e name] UTF8String], [[e reason] UTF8String])
.get());
mozilla::Unused << e;
}
return data;
@ -80,7 +82,8 @@ void nsClipboard::SetSelectionCache(nsITransferable* aTransferable) {
void nsClipboard::ClearSelectionCache() { SetSelectionCache(nullptr); }
NS_IMETHODIMP
nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable,
nsIClipboardOwner* aOwner,
int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@ -92,7 +95,8 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboard
return NS_OK;
}
NSDictionary* pasteboardOutputDict = PasteboardDictFromTransferable(aTransferable);
NSDictionary* pasteboardOutputDict =
PasteboardDictFromTransferable(aTransferable);
if (!pasteboardOutputDict) return NS_ERROR_FAILURE;
unsigned int outputCount = [pasteboardOutputDict count];
@ -100,8 +104,10 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboard
NSPasteboard* cocoaPasteboard = GetPasteboard(aWhichClipboard);
MOZ_ASSERT(cocoaPasteboard);
if (aWhichClipboard == kFindClipboard) {
NSString* stringType = [UTIHelper stringFromPboardType:NSPasteboardTypeString];
[cocoaPasteboard declareTypes:[NSArray arrayWithObject:stringType] owner:nil];
NSString* stringType =
[UTIHelper stringFromPboardType:NSPasteboardTypeString];
[cocoaPasteboard declareTypes:[NSArray arrayWithObject:stringType]
owner:nil];
} else {
// Write everything else out to the general pasteboard.
MOZ_ASSERT(aWhichClipboard == kGlobalClipboard);
@ -112,32 +118,48 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboard
NSString* currentKey = [outputKeys objectAtIndex:i];
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
if (aWhichClipboard == kFindClipboard) {
if ([currentKey isEqualToString:[UTIHelper stringFromPboardType:NSPasteboardTypeString]]) {
if ([currentKey isEqualToString:[UTIHelper stringFromPboardType:
NSPasteboardTypeString]]) {
[cocoaPasteboard setString:currentValue forType:currentKey];
}
} else {
if ([currentKey isEqualToString:[UTIHelper stringFromPboardType:NSPasteboardTypeString]] ||
[currentKey isEqualToString:[UTIHelper stringFromPboardType:kPublicUrlPboardType]] ||
[currentKey isEqualToString:[UTIHelper stringFromPboardType:kPublicUrlNamePboardType]]) {
if ([currentKey isEqualToString:[UTIHelper stringFromPboardType:
NSPasteboardTypeString]] ||
[currentKey
isEqualToString:[UTIHelper
stringFromPboardType:kPublicUrlPboardType]] ||
[currentKey
isEqualToString:
[UTIHelper stringFromPboardType:kPublicUrlNamePboardType]]) {
[cocoaPasteboard setString:currentValue forType:currentKey];
} else if ([currentKey
isEqualToString:[UTIHelper stringFromPboardType:kUrlsWithTitlesPboardType]]) {
[cocoaPasteboard setPropertyList:[pasteboardOutputDict valueForKey:currentKey]
forType:currentKey];
isEqualToString:
[UTIHelper
stringFromPboardType:kUrlsWithTitlesPboardType]]) {
[cocoaPasteboard
setPropertyList:[pasteboardOutputDict valueForKey:currentKey]
forType:currentKey];
} else if ([currentKey
isEqualToString:[UTIHelper stringFromPboardType:NSPasteboardTypeHTML]]) {
[cocoaPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
forType:currentKey];
isEqualToString:[UTIHelper stringFromPboardType:
NSPasteboardTypeHTML]]) {
[cocoaPasteboard
setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
forType:currentKey];
} else if ([currentKey
isEqualToString:[UTIHelper stringFromPboardType:kMozFileUrlsPboardType]]) {
isEqualToString:[UTIHelper stringFromPboardType:
kMozFileUrlsPboardType]]) {
[cocoaPasteboard writeObjects:currentValue];
} else if ([currentKey
isEqualToString:[UTIHelper stringFromPboardType:(NSString*)kUTTypeFileURL]]) {
isEqualToString:
[UTIHelper
stringFromPboardType:(NSString*)kUTTypeFileURL]]) {
[cocoaPasteboard setString:currentValue forType:currentKey];
} else if ([currentKey
isEqualToString:[UTIHelper stringFromPboardType:kPasteboardConcealedType]]) {
// It's fine to set the data to null for this field - this field is an addition
// to a value's other type and works like a flag.
isEqualToString:
[UTIHelper
stringFromPboardType:kPasteboardConcealedType]]) {
// It's fine to set the data to null for this field - this field is an
// addition to a value's other type and works like a flag.
[cocoaPasteboard setData:NULL forType:currentKey];
} else {
[cocoaPasteboard setData:currentValue forType:currentKey];
@ -150,12 +172,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboard
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
NSPasteboard* cocoaPasteboard) {
nsresult nsClipboard::TransferableFromPasteboard(
nsITransferable* aTransferable, NSPasteboard* cocoaPasteboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
// get flavor list that includes all acceptable flavors (including ones
// obtained through conversion)
nsTArray<nsCString> flavors;
nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
@ -173,8 +195,8 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
}
NSData* stringData;
bool isRTF =
[pboardType isEqualToString:[UTIHelper stringFromPboardType:NSPasteboardTypeRTF]];
bool isRTF = [pboardType
isEqualToString:[UTIHelper stringFromPboardType:NSPasteboardTypeRTF]];
if (isRTF) {
stringData = [pString dataUsingEncoding:NSASCIIStringEncoding];
} else {
@ -187,23 +209,25 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
}
[stringData getBytes:clipboardDataPtr length:dataLength];
// The DOM only wants LF, so convert from MacOS line endings to DOM line endings.
// The DOM only wants LF, so convert from MacOS line endings to DOM line
// endings.
int32_t signedDataLength = dataLength;
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(isRTF, &clipboardDataPtr,
&signedDataLength);
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(
isRTF, &clipboardDataPtr, &signedDataLength);
dataLength = signedDataLength;
// skip BOM (Byte Order Mark to distinguish little or big endian)
char16_t* clipboardDataPtrNoBOM = (char16_t*)clipboardDataPtr;
if ((dataLength > 2) &&
((clipboardDataPtrNoBOM[0] == 0xFEFF) || (clipboardDataPtrNoBOM[0] == 0xFFFE))) {
if ((dataLength > 2) && ((clipboardDataPtrNoBOM[0] == 0xFEFF) ||
(clipboardDataPtrNoBOM[0] == 0xFFFE))) {
dataLength -= sizeof(char16_t);
clipboardDataPtrNoBOM += 1;
}
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtrNoBOM, dataLength,
getter_AddRefs(genericDataWrapper));
nsPrimitiveHelpers::CreatePrimitiveForData(
flavorStr, clipboardDataPtrNoBOM, dataLength,
getter_AddRefs(genericDataWrapper));
aTransferable->SetTransferData(flavorStr.get(), genericDataWrapper);
free(clipboardDataPtr);
break;
@ -220,11 +244,14 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
continue;
}
nsCocoaUtils::SetTransferDataForTypeFromPasteboardItem(aTransferable, flavorStr, item);
nsCocoaUtils::SetTransferDataForTypeFromPasteboardItem(aTransferable,
flavorStr, item);
} else if (flavorStr.EqualsLiteral(kCustomTypesMime)) {
NSString* type = [cocoaPasteboard
availableTypeFromArray:
[NSArray arrayWithObject:[UTIHelper stringFromPboardType:kMozCustomTypesPboardType]]];
[NSArray
arrayWithObject:[UTIHelper stringFromPboardType:
kMozCustomTypesPboardType]]];
if (!type) {
continue;
}
@ -242,19 +269,26 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
[pasteboardData getBytes:clipboardDataPtr length:dataLength];
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength,
getter_AddRefs(genericDataWrapper));
nsPrimitiveHelpers::CreatePrimitiveForData(
flavorStr, clipboardDataPtr, dataLength,
getter_AddRefs(genericDataWrapper));
aTransferable->SetTransferData(flavorStr.get(), genericDataWrapper);
free(clipboardDataPtr);
} else if (flavorStr.EqualsLiteral(kJPEGImageMime) || flavorStr.EqualsLiteral(kJPGImageMime) ||
flavorStr.EqualsLiteral(kPNGImageMime) || flavorStr.EqualsLiteral(kGIFImageMime)) {
} else if (flavorStr.EqualsLiteral(kJPEGImageMime) ||
flavorStr.EqualsLiteral(kJPGImageMime) ||
flavorStr.EqualsLiteral(kPNGImageMime) ||
flavorStr.EqualsLiteral(kGIFImageMime)) {
// Figure out if there's data on the pasteboard we can grab (sanity check)
NSString* type = [cocoaPasteboard
availableTypeFromArray:
[NSArray arrayWithObjects:[UTIHelper stringFromPboardType:(NSString*)kUTTypeFileURL],
[UTIHelper stringFromPboardType:NSPasteboardTypeTIFF],
[UTIHelper stringFromPboardType:NSPasteboardTypePNG], nil]];
[NSArray
arrayWithObjects:
[UTIHelper
stringFromPboardType:(NSString*)kUTTypeFileURL],
[UTIHelper stringFromPboardType:NSPasteboardTypeTIFF],
[UTIHelper stringFromPboardType:NSPasteboardTypePNG],
nil]];
if (!type) continue;
// Read data off the clipboard
@ -263,7 +297,8 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
// Figure out what type we're converting to
CFStringRef outputType = NULL;
if (flavorStr.EqualsLiteral(kJPEGImageMime) || flavorStr.EqualsLiteral(kJPGImageMime))
if (flavorStr.EqualsLiteral(kJPEGImageMime) ||
flavorStr.EqualsLiteral(kJPGImageMime))
outputType = CFSTR("public.jpeg");
else if (flavorStr.EqualsLiteral(kPNGImageMime))
outputType = CFSTR("public.png");
@ -276,20 +311,23 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
// Note that ImageIO, like all CF APIs, allows NULLs to propagate freely
// and safely in most cases (like ObjC). A notable exception is CFRelease.
NSDictionary* options = [NSDictionary
dictionaryWithObjectsAndKeys:(NSNumber*)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
type, kCGImageSourceTypeIdentifierHint, nil];
dictionaryWithObjectsAndKeys:(NSNumber*)kCFBooleanTrue,
kCGImageSourceShouldAllowFloat, type,
kCGImageSourceTypeIdentifierHint, nil];
CGImageSourceRef source = nullptr;
if (type == [UTIHelper stringFromPboardType:(NSString*)kUTTypeFileURL]) {
NSString* urlStr = [cocoaPasteboard stringForType:type];
NSURL* url = [NSURL URLWithString:urlStr];
source = CGImageSourceCreateWithURL((CFURLRef)url, (CFDictionaryRef)options);
source =
CGImageSourceCreateWithURL((CFURLRef)url, (CFDictionaryRef)options);
} else {
source = CGImageSourceCreateWithData((CFDataRef)pasteboardData, (CFDictionaryRef)options);
source = CGImageSourceCreateWithData((CFDataRef)pasteboardData,
(CFDictionaryRef)options);
}
NSMutableData* encodedData = [NSMutableData data];
CGImageDestinationRef dest =
CGImageDestinationCreateWithData((CFMutableDataRef)encodedData, outputType, 1, NULL);
CGImageDestinationRef dest = CGImageDestinationCreateWithData(
(CFMutableDataRef)encodedData, outputType, 1, NULL);
CGImageDestinationAddImageFromSource(dest, source, 0, NULL);
bool successfullyConverted = CGImageDestinationFinalize(dest);
@ -297,7 +335,8 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
// Put the converted data in a form Gecko can understand
nsCOMPtr<nsIInputStream> byteStream;
NS_NewByteInputStream(getter_AddRefs(byteStream),
mozilla::Span((const char*)[encodedData bytes], [encodedData length]),
mozilla::Span((const char*)[encodedData bytes],
[encodedData length]),
NS_ASSIGNMENT_COPY);
aTransferable->SetTransferData(flavorStr.get(), byteStream);
@ -321,19 +360,21 @@ nsresult nsClipboard::TransferableFromPasteboard(nsITransferable* aTransferable,
}
NS_IMETHODIMP
nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable,
int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_DIAGNOSTIC_ASSERT(aTransferable);
MOZ_DIAGNOSTIC_ASSERT(nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
MOZ_DIAGNOSTIC_ASSERT(
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
if (kSelectionCache == aWhichClipboard) {
if (!sSelectionCache) {
return NS_OK;
}
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
// get flavor list that includes all acceptable flavors (including ones
// obtained through conversion)
nsTArray<nsCString> flavors;
nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
if (NS_FAILED(rv)) {
@ -342,7 +383,8 @@ nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhi
for (const auto& flavor : flavors) {
nsCOMPtr<nsISupports> dataSupports;
rv = sSelectionCache->GetTransferData(flavor.get(), getter_AddRefs(dataSupports));
rv = sSelectionCache->GetTransferData(flavor.get(),
getter_AddRefs(dataSupports));
if (NS_SUCCEEDED(rv)) {
CLIPBOARD_LOG("%s: getting %s from cache.", __FUNCTION__, flavor.get());
aTransferable->SetTransferData(flavor.get(), dataSupports);
@ -364,18 +406,22 @@ nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhi
}
// returns true if we have *any* of the passed in flavors available for pasting
mozilla::Result<bool, nsresult> nsClipboard::HasNativeClipboardDataMatchingFlavors(
mozilla::Result<bool, nsresult>
nsClipboard::HasNativeClipboardDataMatchingFlavors(
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_DIAGNOSTIC_ASSERT(nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
MOZ_DIAGNOSTIC_ASSERT(
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
if (kSelectionCache == aWhichClipboard) {
nsTArray<nsCString> transferableFlavors;
if (sSelectionCache &&
NS_SUCCEEDED(sSelectionCache->FlavorsTransferableCanImport(transferableFlavors))) {
NS_SUCCEEDED(sSelectionCache->FlavorsTransferableCanImport(
transferableFlavors))) {
if (CLIPBOARD_LOG_ENABLED()) {
CLIPBOARD_LOG(" SelectionCache types (nums %zu)\n", transferableFlavors.Length());
CLIPBOARD_LOG(" SelectionCache types (nums %zu)\n",
transferableFlavors.Length());
for (const auto& transferableFlavor : transferableFlavors) {
CLIPBOARD_LOG(" MIME %s", transferableFlavor.get());
}
@ -417,8 +463,8 @@ mozilla::Result<bool, nsresult> nsClipboard::HasNativeClipboardDataMatchingFlavo
for (auto& mimeType : aFlavorList) {
NSString* pboardType = nil;
if (nsClipboard::IsStringType(mimeType, &pboardType)) {
NSString* availableType =
[cocoaPasteboard availableTypeFromArray:[NSArray arrayWithObject:pboardType]];
NSString* availableType = [cocoaPasteboard
availableTypeFromArray:[NSArray arrayWithObject:pboardType]];
if (availableType && [availableType isEqualToString:pboardType]) {
CLIPBOARD_LOG(" has %s\n", mimeType.get());
return true;
@ -426,17 +472,24 @@ mozilla::Result<bool, nsresult> nsClipboard::HasNativeClipboardDataMatchingFlavo
} else if (mimeType.EqualsLiteral(kCustomTypesMime)) {
NSString* availableType = [cocoaPasteboard
availableTypeFromArray:
[NSArray arrayWithObject:[UTIHelper stringFromPboardType:kMozCustomTypesPboardType]]];
[NSArray
arrayWithObject:[UTIHelper stringFromPboardType:
kMozCustomTypesPboardType]]];
if (availableType) {
CLIPBOARD_LOG(" has %s\n", mimeType.get());
return true;
}
} else if (mimeType.EqualsLiteral(kJPEGImageMime) || mimeType.EqualsLiteral(kJPGImageMime) ||
mimeType.EqualsLiteral(kPNGImageMime) || mimeType.EqualsLiteral(kGIFImageMime)) {
} else if (mimeType.EqualsLiteral(kJPEGImageMime) ||
mimeType.EqualsLiteral(kJPGImageMime) ||
mimeType.EqualsLiteral(kPNGImageMime) ||
mimeType.EqualsLiteral(kGIFImageMime)) {
NSString* availableType = [cocoaPasteboard
availableTypeFromArray:
[NSArray arrayWithObjects:[UTIHelper stringFromPboardType:NSPasteboardTypeTIFF],
[UTIHelper stringFromPboardType:NSPasteboardTypePNG], nil]];
[NSArray
arrayWithObjects:
[UTIHelper stringFromPboardType:NSPasteboardTypeTIFF],
[UTIHelper stringFromPboardType:NSPasteboardTypePNG],
nil]];
if (availableType) {
CLIPBOARD_LOG(" has %s\n", mimeType.get());
return true;
@ -449,9 +502,11 @@ mozilla::Result<bool, nsresult> nsClipboard::HasNativeClipboardDataMatchingFlavo
if (NSPasteboardItem* item = [items objectAtIndex:0]) {
if (NSString *availableType = [item
availableTypeFromArray:
[NSArray arrayWithObjects:[UTIHelper
stringFromPboardType:(NSString*)kUTTypeFileURL],
nil]]) {
[NSArray
arrayWithObjects:[UTIHelper
stringFromPboardType:
(NSString*)kUTTypeFileURL],
nil]]) {
CLIPBOARD_LOG(" has %s\n", mimeType.get());
return true;
}
@ -481,10 +536,10 @@ mozilla::Maybe<uint32_t> nsClipboard::FindIndexOfImageFlavor(
return mozilla::Nothing();
}
// This function converts anything that other applications might understand into the system format
// and puts it into a dictionary which it returns.
// static
NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable) {
// This function converts anything that other applications might understand into
// the system format and puts it into a dictionary which it returns. static
NSDictionary* nsClipboard::PasteboardDictFromTransferable(
nsITransferable* aTransferable) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (!aTransferable) {
@ -499,29 +554,33 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
return nil;
}
const mozilla::Maybe<uint32_t> imageFlavorIndex = nsClipboard::FindIndexOfImageFlavor(flavors);
const mozilla::Maybe<uint32_t> imageFlavorIndex =
nsClipboard::FindIndexOfImageFlavor(flavors);
if (imageFlavorIndex) {
// When right-clicking and "Copy Image" is clicked on macOS, some apps expect the
// first flavor to be the image flavor. See bug 1689992. For other apps, the
// order shouldn't matter.
// When right-clicking and "Copy Image" is clicked on macOS, some apps
// expect the first flavor to be the image flavor. See bug 1689992. For
// other apps, the order shouldn't matter.
std::swap(*flavors.begin(), flavors[*imageFlavorIndex]);
}
for (uint32_t i = 0; i < flavors.Length(); i++) {
nsCString& flavorStr = flavors[i];
CLIPBOARD_LOG("writing out clipboard data of type %s (%d)\n", flavorStr.get(), i);
CLIPBOARD_LOG("writing out clipboard data of type %s (%d)\n",
flavorStr.get(), i);
NSString* pboardType = nil;
if (nsClipboard::IsStringType(flavorStr, &pboardType)) {
nsCOMPtr<nsISupports> genericDataWrapper;
rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(genericDataWrapper));
rv = aTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(genericDataWrapper));
if (NS_FAILED(rv)) {
continue;
}
nsAutoString data;
if (nsCOMPtr<nsISupportsString> text = do_QueryInterface(genericDataWrapper)) {
if (nsCOMPtr<nsISupportsString> text =
do_QueryInterface(genericDataWrapper)) {
text->GetData(data);
}
@ -540,26 +599,32 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
}
if (aTransferable->GetIsPrivateData()) {
// In the case of password strings, we want to include the key for concealed type.
// These will be flagged as private data.
[pasteboardOutputDict setObject:nativeString
forKey:[UTIHelper stringFromPboardType:kPasteboardConcealedType]];
// In the case of password strings, we want to include the key for
// concealed type. These will be flagged as private data.
[pasteboardOutputDict
setObject:nativeString
forKey:[UTIHelper
stringFromPboardType:kPasteboardConcealedType]];
}
} else if (flavorStr.EqualsLiteral(kCustomTypesMime)) {
nsCOMPtr<nsISupports> genericDataWrapper;
rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(genericDataWrapper));
rv = aTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(genericDataWrapper));
if (NS_FAILED(rv)) {
continue;
}
nsAutoCString data;
if (nsCOMPtr<nsISupportsCString> text = do_QueryInterface(genericDataWrapper)) {
if (nsCOMPtr<nsISupportsCString> text =
do_QueryInterface(genericDataWrapper)) {
text->GetData(data);
}
if (!data.IsEmpty()) {
NSData* nativeData = [NSData dataWithBytes:data.get() length:data.Length()];
NSString* customType = [UTIHelper stringFromPboardType:kMozCustomTypesPboardType];
NSData* nativeData = [NSData dataWithBytes:data.get()
length:data.Length()];
NSString* customType =
[UTIHelper stringFromPboardType:kMozCustomTypesPboardType];
if (!nativeData) {
continue;
}
@ -567,7 +632,8 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
}
} else if (nsClipboard::IsImageType(flavorStr)) {
nsCOMPtr<nsISupports> transferSupports;
rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(transferSupports));
rv = aTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(transferSupports));
if (NS_FAILED(rv)) {
continue;
}
@ -578,9 +644,9 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
continue;
}
RefPtr<SourceSurface> surface =
image->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
RefPtr<SourceSurface> surface = image->GetFrame(
imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
if (!surface) {
continue;
}
@ -592,8 +658,8 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
// Convert the CGImageRef to TIFF data.
CFMutableDataRef tiffData = CFDataCreateMutable(kCFAllocatorDefault, 0);
CGImageDestinationRef destRef =
CGImageDestinationCreateWithData(tiffData, CFSTR("public.tiff"), 1, NULL);
CGImageDestinationRef destRef = CGImageDestinationCreateWithData(
tiffData, CFSTR("public.tiff"), 1, NULL);
CGImageDestinationAddImage(destRef, imageRef, NULL);
bool successfullyConverted = CGImageDestinationFinalize(destRef);
@ -609,12 +675,14 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
continue;
}
NSString* tiffType = [UTIHelper stringFromPboardType:NSPasteboardTypeTIFF];
NSString* tiffType =
[UTIHelper stringFromPboardType:NSPasteboardTypeTIFF];
[pasteboardOutputDict setObject:(NSMutableData*)tiffData forKey:tiffType];
CFRelease(tiffData);
} else if (flavorStr.EqualsLiteral(kFileMime)) {
nsCOMPtr<nsISupports> genericFile;
rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(genericFile));
rv = aTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(genericFile));
if (NS_FAILED(rv)) {
continue;
}
@ -635,18 +703,22 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
if (!url || ![url absoluteString]) {
continue;
}
NSString* fileUTType = [UTIHelper stringFromPboardType:(NSString*)kUTTypeFileURL];
NSString* fileUTType =
[UTIHelper stringFromPboardType:(NSString*)kUTTypeFileURL];
[pasteboardOutputDict setObject:[url absoluteString] forKey:fileUTType];
} else if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
NSString* urlPromise =
[UTIHelper stringFromPboardType:(NSString*)kPasteboardTypeFileURLPromise];
NSString* urlPromiseContent =
[UTIHelper stringFromPboardType:(NSString*)kPasteboardTypeFilePromiseContent];
[pasteboardOutputDict setObject:[NSArray arrayWithObject:@""] forKey:urlPromise];
[pasteboardOutputDict setObject:[NSArray arrayWithObject:@""] forKey:urlPromiseContent];
NSString* urlPromise = [UTIHelper
stringFromPboardType:(NSString*)kPasteboardTypeFileURLPromise];
NSString* urlPromiseContent = [UTIHelper
stringFromPboardType:(NSString*)kPasteboardTypeFilePromiseContent];
[pasteboardOutputDict setObject:[NSArray arrayWithObject:@""]
forKey:urlPromise];
[pasteboardOutputDict setObject:[NSArray arrayWithObject:@""]
forKey:urlPromiseContent];
} else if (flavorStr.EqualsLiteral(kURLMime)) {
nsCOMPtr<nsISupports> genericURL;
rv = aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(genericURL));
rv = aTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(genericURL));
nsCOMPtr<nsISupportsString> urlObject(do_QueryInterface(genericURL));
nsAutoString url;
@ -662,10 +734,12 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
nsAutoString urlTitle;
urlObject->GetData(urlTitle);
urlTitle.Mid(urlTitle, newlinePos + 1, urlTitle.Length() - (newlinePos + 1));
urlTitle.Mid(urlTitle, newlinePos + 1,
urlTitle.Length() - (newlinePos + 1));
nativeTitle =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(urlTitle.get())
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
urlTitle.get())
length:urlTitle.Length()];
}
// The Finder doesn't like getting random binary data aka
@ -673,24 +747,29 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
// ASCII.
nsAutoCString utf8Data = NS_ConvertUTF16toUTF8(url.get(), url.Length());
nsAutoCString escData;
NS_EscapeURL(utf8Data.get(), utf8Data.Length(), esc_OnlyNonASCII | esc_AlwaysCopy, escData);
NS_EscapeURL(utf8Data.get(), utf8Data.Length(),
esc_OnlyNonASCII | esc_AlwaysCopy, escData);
NSString* nativeURL = [NSString stringWithUTF8String:escData.get()];
NSString* publicUrl = [UTIHelper stringFromPboardType:kPublicUrlPboardType];
NSString* publicUrl =
[UTIHelper stringFromPboardType:kPublicUrlPboardType];
if (!nativeURL) {
continue;
}
[pasteboardOutputDict setObject:nativeURL forKey:publicUrl];
if (nativeTitle) {
NSArray* urlsAndTitles = @[ @[ nativeURL ], @[ nativeTitle ] ];
NSString* urlName = [UTIHelper stringFromPboardType:kPublicUrlNamePboardType];
NSString* urlsWithTitles = [UTIHelper stringFromPboardType:kUrlsWithTitlesPboardType];
NSString* urlName =
[UTIHelper stringFromPboardType:kPublicUrlNamePboardType];
NSString* urlsWithTitles =
[UTIHelper stringFromPboardType:kUrlsWithTitlesPboardType];
[pasteboardOutputDict setObject:nativeTitle forKey:urlName];
[pasteboardOutputDict setObject:urlsAndTitles forKey:urlsWithTitles];
}
}
// If it wasn't a type that we recognize as exportable we don't put it on the system
// clipboard. We'll just access it from our cached transferable when we need it.
// If it wasn't a type that we recognize as exportable we don't put it on
// the system clipboard. We'll just access it from our cached transferable
// when we need it.
}
return pasteboardOutputDict;
@ -698,7 +777,8 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
bool nsClipboard::IsStringType(const nsCString& aMIMEType, NSString** aPboardType) {
bool nsClipboard::IsStringType(const nsCString& aMIMEType,
NSString** aPboardType) {
if (aMIMEType.EqualsLiteral(kTextMime)) {
*aPboardType = [UTIHelper stringFromPboardType:NSPasteboardTypeString];
return true;
@ -715,29 +795,33 @@ bool nsClipboard::IsStringType(const nsCString& aMIMEType, NSString** aPboardTyp
// static
bool nsClipboard::IsImageType(const nsACString& aMIMEType) {
return aMIMEType.EqualsLiteral(kPNGImageMime) || aMIMEType.EqualsLiteral(kJPEGImageMime) ||
aMIMEType.EqualsLiteral(kJPGImageMime) || aMIMEType.EqualsLiteral(kGIFImageMime) ||
return aMIMEType.EqualsLiteral(kPNGImageMime) ||
aMIMEType.EqualsLiteral(kJPEGImageMime) ||
aMIMEType.EqualsLiteral(kJPGImageMime) ||
aMIMEType.EqualsLiteral(kGIFImageMime) ||
aMIMEType.EqualsLiteral(kNativeImageMime);
}
NSString* nsClipboard::WrapHtmlForSystemPasteboard(NSString* aString) {
NSString* wrapped = [NSString
stringWithFormat:@"<html>"
"<head>"
"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"
"</head>"
"<body>"
"%@"
"</body>"
"</html>",
aString];
NSString* wrapped =
[NSString stringWithFormat:@"<html>"
"<head>"
"<meta http-equiv=\"content-type\" "
"content=\"text/html; charset=utf-8\">"
"</head>"
"<body>"
"%@"
"</body>"
"</html>",
aString];
return wrapped;
}
nsresult nsClipboard::EmptyNativeClipboardData(int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_DIAGNOSTIC_ASSERT(nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
MOZ_DIAGNOSTIC_ASSERT(
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
if (kSelectionCache == aWhichClipboard) {
ClearSelectionCache();
@ -753,11 +837,12 @@ nsresult nsClipboard::EmptyNativeClipboardData(int32_t aWhichClipboard) {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
mozilla::Result<int32_t, nsresult> nsClipboard::GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) {
mozilla::Result<int32_t, nsresult>
nsClipboard::GetNativeClipboardSequenceNumber(int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_DIAGNOSTIC_ASSERT(nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
MOZ_DIAGNOSTIC_ASSERT(
nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
if (kSelectionCache == aWhichClipboard) {
return sSelectionCacheChangeCount;

Просмотреть файл

@ -38,7 +38,8 @@
/*static*/ int32_t nsCocoaFeatures::mOSVersion = 0;
// This should not be called with unchecked aMajor, which should be >= 10.
inline int32_t AssembleVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix) {
inline int32_t AssembleVersion(int32_t aMajor, int32_t aMinor,
int32_t aBugFix) {
MOZ_ASSERT(aMajor >= 10);
return (aMajor << 16) + (aMinor << 8) + aBugFix;
}
@ -65,11 +66,13 @@ static int intAtStringIndex(NSArray* array, int index) {
void nsCocoaFeatures::GetSystemVersion(int& major, int& minor, int& bugfix) {
major = minor = bugfix = 0;
NSString* versionString = [[NSDictionary
dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]
objectForKey:@"ProductVersion"];
NSString* versionString =
[[NSDictionary dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"]
objectForKey:@"ProductVersion"];
if (!versionString) {
NS_ERROR("Couldn't read /System/Library/CoreServices/SystemVersion.plist to determine macOS "
NS_ERROR("Couldn't read /System/Library/CoreServices/SystemVersion.plist "
"to determine macOS "
"version.");
return;
}
@ -86,7 +89,8 @@ void nsCocoaFeatures::GetSystemVersion(int& major, int& minor, int& bugfix) {
}
}
int32_t nsCocoaFeatures::GetVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix) {
int32_t nsCocoaFeatures::GetVersion(int32_t aMajor, int32_t aMinor,
int32_t aBugFix) {
int32_t macOSVersion;
if (aMajor < 10) {
aMajor = 10;
@ -148,7 +152,8 @@ int32_t nsCocoaFeatures::GetVersion(int32_t aMajor, int32_t aMinor, int32_t aBug
}
/* static */ bool nsCocoaFeatures::OnSierraExactly() {
return (macOSVersion() >= MACOS_VERSION_10_12_HEX) && (macOSVersion() < MACOS_VERSION_10_13_HEX);
return (macOSVersion() >= MACOS_VERSION_10_12_HEX) &&
(macOSVersion() < MACOS_VERSION_10_13_HEX);
}
/* Version of OnSierraExactly as global function callable from cairo & skia */
@ -195,7 +200,8 @@ bool Gecko_OnSierraExactly() { return nsCocoaFeatures::OnSierraExactly(); }
return (macOSVersion() >= MACOS_VERSION_13_0_HEX);
}
/* static */ bool nsCocoaFeatures::IsAtLeastVersion(int32_t aMajor, int32_t aMinor,
/* static */ bool nsCocoaFeatures::IsAtLeastVersion(int32_t aMajor,
int32_t aMinor,
int32_t aBugFix) {
return macOSVersion() >= GetVersion(aMajor, aMinor, aBugFix);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -96,25 +96,30 @@ nsColorPicker::~nsColorPicker() {
// TODO(bug 1805397): Implement default colors
NS_IMETHODIMP
nsColorPicker::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
const nsAString& aInitialColor, const nsTArray<nsString>& aDefaultColors) {
MOZ_ASSERT(NS_IsMainThread(), "Color pickers can only be opened from main thread currently");
const nsAString& aInitialColor,
const nsTArray<nsString>& aDefaultColors) {
MOZ_ASSERT(NS_IsMainThread(),
"Color pickers can only be opened from main thread currently");
mTitle = aTitle;
mColor = aInitialColor;
mColorPanelWrapper = [[NSColorPanelWrapper alloc] initWithPicker:this];
return NS_OK;
}
/* static */ NSColor* nsColorPicker::GetNSColorFromHexString(const nsAString& aColor) {
/* static */ NSColor* nsColorPicker::GetNSColorFromHexString(
const nsAString& aColor) {
NSString* str = nsCocoaUtils::ToNSString(aColor);
double red = HexStrToInt([str substringWithRange:NSMakeRange(1, 2)]) / 255.0;
double green = HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0;
double green =
HexStrToInt([str substringWithRange:NSMakeRange(3, 2)]) / 255.0;
double blue = HexStrToInt([str substringWithRange:NSMakeRange(5, 2)]) / 255.0;
return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0];
}
/* static */ void nsColorPicker::GetHexStringFromNSColor(NSColor* aColor, nsAString& aResult) {
/* static */ void nsColorPicker::GetHexStringFromNSColor(NSColor* aColor,
nsAString& aResult) {
CGFloat redFloat, greenFloat, blueFloat;
NSColor* color = aColor;
@ -126,7 +131,8 @@ nsColorPicker::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
}
nsCocoaUtils::GetStringForNSString(
[NSString stringWithFormat:@"#%02x%02x%02x", (int)(redFloat * 255), (int)(greenFloat * 255),
[NSString stringWithFormat:@"#%02x%02x%02x", (int)(redFloat * 255),
(int)(greenFloat * 255),
(int)(blueFloat * 255)],
aResult);
}
@ -136,7 +142,8 @@ nsColorPicker::Open(nsIColorPickerShownCallback* aCallback) {
MOZ_ASSERT(aCallback);
mCallback = aCallback;
[mColorPanelWrapper open:GetNSColorFromHexString(mColor) title:nsCocoaUtils::ToNSString(mTitle)];
[mColorPanelWrapper open:GetNSColorFromHexString(mColor)
title:nsCocoaUtils::ToNSString(mTitle)];
NS_ADDREF_THIS();

Просмотреть файл

@ -20,8 +20,8 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
/*! @method getCursor:
@abstract Get a reference to the native Mac representation of a cursor.
@discussion Gets a reference to the Mac native implementation of a cursor.
If the cursor has been requested before, it is retreived from the cursor cache,
otherwise it is created and cached.
If the cursor has been requested before, it is retreived from
the cursor cache, otherwise it is created and cached.
@param aCursor the cursor to get
@result the Mac native implementation of the cursor
*/
@ -29,8 +29,9 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
/*! @method setMacCursor:
@abstract Set the current Mac native cursor
@discussion Sets the current cursor - this routine is what actually causes the cursor to change.
The argument is retained and the old cursor is released.
@discussion Sets the current cursor - this routine is what actually causes the
cursor to change. The argument is retained and the old cursor is
released.
@param aMacCursor the cursor to set
@result NS_OK
*/
@ -38,7 +39,8 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
/*! @method createCursor:
@abstract Create a Mac native representation of a cursor.
@discussion Creates a version of the Mac native representation of this cursor
@discussion Creates a version of the Mac native representation of this
cursor.
@param aCursor the cursor to create
@result the Mac native implementation of the cursor
*/
@ -76,92 +78,128 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
return [nsMacCursor cursorWithCursor:[NSCursor arrowCursor] type:aCursor];
case eCursor_wait:
case eCursor_spinning: {
return [nsMacCursor cursorWithCursor:[NSCursor busyButClickableCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor busyButClickableCursor]
type:aCursor];
}
case eCursor_select:
return [nsMacCursor cursorWithCursor:[NSCursor IBeamCursor] type:aCursor];
case eCursor_hyperlink:
return [nsMacCursor cursorWithCursor:[NSCursor pointingHandCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor pointingHandCursor]
type:aCursor];
case eCursor_crosshair:
return [nsMacCursor cursorWithCursor:[NSCursor crosshairCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor crosshairCursor]
type:aCursor];
case eCursor_move:
return [nsMacCursor cursorWithImageNamed:@"move" hotSpot:NSMakePoint(12, 12) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"move"
hotSpot:NSMakePoint(12, 12)
type:aCursor];
case eCursor_help:
return [nsMacCursor cursorWithImageNamed:@"help" hotSpot:NSMakePoint(12, 12) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"help"
hotSpot:NSMakePoint(12, 12)
type:aCursor];
case eCursor_copy: {
SEL cursorSelector = @selector(dragCopyCursor);
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
return [nsMacCursor
cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
}
case eCursor_alias: {
SEL cursorSelector = @selector(dragLinkCursor);
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
return [nsMacCursor
cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
}
case eCursor_context_menu: {
SEL cursorSelector = @selector(contextualMenuCursor);
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
return [nsMacCursor
cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
}
case eCursor_cell:
return [nsMacCursor cursorWithImageNamed:@"cell" hotSpot:NSMakePoint(12, 12) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"cell"
hotSpot:NSMakePoint(12, 12)
type:aCursor];
case eCursor_grab:
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor]
type:aCursor];
case eCursor_grabbing:
return [nsMacCursor cursorWithCursor:[NSCursor closedHandCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor closedHandCursor]
type:aCursor];
case eCursor_zoom_in:
return [nsMacCursor cursorWithImageNamed:@"zoomIn" hotSpot:NSMakePoint(10, 10) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"zoomIn"
hotSpot:NSMakePoint(10, 10)
type:aCursor];
case eCursor_zoom_out:
return [nsMacCursor cursorWithImageNamed:@"zoomOut" hotSpot:NSMakePoint(10, 10) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"zoomOut"
hotSpot:NSMakePoint(10, 10)
type:aCursor];
case eCursor_vertical_text:
return [nsMacCursor cursorWithImageNamed:@"vtIBeam" hotSpot:NSMakePoint(12, 11) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"vtIBeam"
hotSpot:NSMakePoint(12, 11)
type:aCursor];
case eCursor_all_scroll:
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor]
type:aCursor];
case eCursor_not_allowed:
case eCursor_no_drop: {
SEL cursorSelector = @selector(operationNotAllowedCursor);
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
return [nsMacCursor
cursorWithCursor:[NSCursor respondsToSelector:cursorSelector]
? [NSCursor performSelector:cursorSelector]
: [NSCursor arrowCursor]
type:aCursor];
}
// Resize Cursors:
// North
case eCursor_n_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpCursor]
type:aCursor];
// North East
case eCursor_ne_resize:
return [nsMacCursor cursorWithImageNamed:@"sizeNE" hotSpot:NSMakePoint(12, 11) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"sizeNE"
hotSpot:NSMakePoint(12, 11)
type:aCursor];
// East
case eCursor_e_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeRightCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeRightCursor]
type:aCursor];
// South East
case eCursor_se_resize:
return [nsMacCursor cursorWithImageNamed:@"sizeSE" hotSpot:NSMakePoint(12, 12) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"sizeSE"
hotSpot:NSMakePoint(12, 12)
type:aCursor];
// South
case eCursor_s_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeDownCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeDownCursor]
type:aCursor];
// South West
case eCursor_sw_resize:
return [nsMacCursor cursorWithImageNamed:@"sizeSW" hotSpot:NSMakePoint(10, 12) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"sizeSW"
hotSpot:NSMakePoint(10, 12)
type:aCursor];
// West
case eCursor_w_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftCursor]
type:aCursor];
// North West
case eCursor_nw_resize:
return [nsMacCursor cursorWithImageNamed:@"sizeNW" hotSpot:NSMakePoint(11, 11) type:aCursor];
return [nsMacCursor cursorWithImageNamed:@"sizeNW"
hotSpot:NSMakePoint(11, 11)
type:aCursor];
// North & South
case eCursor_ns_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpDownCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpDownCursor]
type:aCursor];
// East & West
case eCursor_ew_resize:
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftRightCursor] type:aCursor];
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftRightCursor]
type:aCursor];
// North East & South West
case eCursor_nesw_resize:
return [nsMacCursor cursorWithImageNamed:@"sizeNESW"
@ -241,8 +279,10 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
widgetScaleFactor:(CGFloat)scaleFactor {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
// As the user moves the mouse, this gets called repeatedly with the same aCursorImage
if (sCurrentCursor == aCursor && sCurrentCursorScaleFactor == scaleFactor && mCurrentMacCursor) {
// As the user moves the mouse, this gets called repeatedly with the same
// aCursorImage
if (sCurrentCursor == aCursor && sCurrentCursorScaleFactor == scaleFactor &&
mCurrentMacCursor) {
// Native dragging can unset our cursor apparently (see bug 1739352).
if (MOZ_UNLIKELY(![mCurrentMacCursor isSet])) {
[mCurrentMacCursor set];
@ -265,7 +305,8 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
NSImage* cursorImage;
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, nullptr, &cursorImage, scaleFactor);
aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, nullptr,
&cursorImage, scaleFactor);
if (NS_FAILED(rv) || !cursorImage) {
return NS_ERROR_FAILURE;
}
@ -277,11 +318,14 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
}
// if the hotspot is nonsensical, make it 0,0
uint32_t hotspotX = aCursor.mHotspotX > (uint32_t(size.width) - 1) ? 0 : aCursor.mHotspotX;
uint32_t hotspotY = aCursor.mHotspotY > (uint32_t(size.height) - 1) ? 0 : aCursor.mHotspotY;
uint32_t hotspotX =
aCursor.mHotspotX > (uint32_t(size.width) - 1) ? 0 : aCursor.mHotspotX;
uint32_t hotspotY =
aCursor.mHotspotY > (uint32_t(size.height) - 1) ? 0 : aCursor.mHotspotY;
NSPoint hotSpot = ::NSMakePoint(hotspotX, hotspotY);
[self setMacCursor:[nsMacCursor cursorWithCursor:[[NSCursor alloc] initWithImage:cursorImage
hotSpot:hotSpot]
[self setMacCursor:[nsMacCursor cursorWithCursor:[[NSCursor alloc]
initWithImage:cursorImage
hotSpot:hotSpot]
type:kCustomCursor]];
[cursorImage release];
return NS_OK;
@ -292,7 +336,8 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
- (nsMacCursor*)getCursor:(enum nsCursor)aCursor {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsMacCursor* result = [mCursors objectForKey:[NSNumber numberWithInt:aCursor]];
nsMacCursor* result =
[mCursors objectForKey:[NSNumber numberWithInt:aCursor]];
if (!result) {
result = [nsCursorManager createCursor:aCursor];
[mCursors setObject:result forKey:[NSNumber numberWithInt:aCursor]];

Просмотреть файл

@ -67,7 +67,8 @@ nsDeviceContextSpecX::~nsDeviceContextSpecX() {
NS_IMPL_ISUPPORTS(nsDeviceContextSpecX, nsIDeviceContextSpec)
NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, bool aIsPrintPreview) {
NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS,
bool aIsPrintPreview) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
RefPtr<nsPrintSettingsX> settings(do_QueryObject(aPS));
@ -81,7 +82,8 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, bool aIsPrintPre
if (!printInfo) {
return NS_ERROR_FAILURE;
}
if (aPS->GetOutputDestination() == nsIPrintSettings::kOutputDestinationStream) {
if (aPS->GetOutputDestination() ==
nsIPrintSettings::kOutputDestinationStream) {
aPS->GetOutputStream(getter_AddRefs(mOutputStream));
if (!mOutputStream) {
return NS_ERROR_FAILURE;
@ -108,17 +110,20 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, bool aIsPrintPre
// TODO: Currently we do not support using SkPDF for kPMDestinationFax or
// kPMDestinationProcessPDF ("Add PDF to iBooks, etc.), and we only support
// it for kPMDestinationFile if the destination file is a PDF.
// XXX Could PMWorkflowSubmitPDFWithSettings/PMPrinterPrintWithProvider help?
// XXX Could PMWorkflowSubmitPDFWithSettings/PMPrinterPrintWithProvider
// help?
OSStatus status = noErr;
PMDestinationType destination;
status = ::PMSessionGetDestinationType(mPrintSession, mPMPrintSettings, &destination);
status = ::PMSessionGetDestinationType(mPrintSession, mPMPrintSettings,
&destination);
if (status == noErr) {
if (destination == kPMDestinationPrinter || destination == kPMDestinationPreview) {
if (destination == kPMDestinationPrinter ||
destination == kPMDestinationPreview) {
mPrintViaSkPDF = true;
} else if (destination == kPMDestinationFile) {
AutoCFRelease<CFURLRef> destURL(nullptr);
status =
::PMSessionCopyDestinationLocation(mPrintSession, mPMPrintSettings, destURL.receive());
status = ::PMSessionCopyDestinationLocation(
mPrintSession, mPMPrintSettings, destURL.receive());
if (status == noErr) {
AutoCFRelease<CFStringRef> destPathRef =
CFURLCopyFileSystemPath(destURL, kCFURLPOSIXPathStyle);
@ -139,16 +144,20 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, bool aIsPrintPre
// We don't actually currently support/use kOutputFormatPDF on mac, but
// this is for completeness in case we add that (we probably need to in
// order to support adding links into saved PDFs, for example).
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, u"pdf_file"_ns, 1);
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
u"pdf_file"_ns, 1);
} else {
PMDestinationType destination;
OSStatus status = ::PMSessionGetDestinationType(mPrintSession, mPMPrintSettings, &destination);
if (status == noErr &&
(destination == kPMDestinationFile || destination == kPMDestinationPreview ||
destination == kPMDestinationProcessPDF)) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, u"pdf_file"_ns, 1);
OSStatus status = ::PMSessionGetDestinationType(
mPrintSession, mPMPrintSettings, &destination);
if (status == noErr && (destination == kPMDestinationFile ||
destination == kPMDestinationPreview ||
destination == kPMDestinationProcessPDF)) {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
u"pdf_file"_ns, 1);
} else {
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE, u"unknown"_ns, 1);
Telemetry::ScalarAdd(Telemetry::ScalarID::PRINTING_TARGET_TYPE,
u"unknown"_ns, 1);
}
}
@ -157,9 +166,9 @@ NS_IMETHODIMP nsDeviceContextSpecX::Init(nsIPrintSettings* aPS, bool aIsPrintPre
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage) {
NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(
const nsAString& aTitle, const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return NS_OK;
@ -168,7 +177,8 @@ NS_IMETHODIMP nsDeviceContextSpecX::BeginDocument(const nsAString& aTitle,
}
RefPtr<PrintEndDocumentPromise> nsDeviceContextSpecX::EndDocument() {
return nsIDeviceContextSpec::EndDocumentPromiseFromResult(DoEndDocument(), __func__);
return nsIDeviceContextSpec::EndDocumentPromiseFromResult(DoEndDocument(),
__func__);
}
nsresult nsDeviceContextSpecX::DoEndDocument() {
@ -183,14 +193,15 @@ nsresult nsDeviceContextSpecX::DoEndDocument() {
return NS_ERROR_FAILURE;
}
AutoCFRelease<CFURLRef> pdfURL(nullptr);
// Note that the caller is responsible to release pdfURL according to nsILocalFileMac.idl,
// even though we didn't follow the Core Foundation naming conventions here (the method
// should've been called CopyCFURL).
// Note that the caller is responsible to release pdfURL according to
// nsILocalFileMac.idl, even though we didn't follow the Core Foundation
// naming conventions here (the method should've been called CopyCFURL).
nsresult rv = tmpPDFFile->GetCFURL(pdfURL.receive());
NS_ENSURE_SUCCESS(rv, rv);
PMDestinationType destination;
status = ::PMSessionGetDestinationType(mPrintSession, mPMPrintSettings, &destination);
status = ::PMSessionGetDestinationType(mPrintSession, mPMPrintSettings,
&destination);
switch (destination) {
case kPMDestinationPrinter: {
@ -200,13 +211,14 @@ nsresult nsDeviceContextSpecX::DoEndDocument() {
return NS_ERROR_FAILURE;
}
CFStringRef mimeType = CFSTR("application/pdf");
status = ::PMPrinterPrintWithFile(currentPrinter, mPMPrintSettings, mPageFormat, mimeType,
pdfURL);
status = ::PMPrinterPrintWithFile(currentPrinter, mPMPrintSettings,
mPageFormat, mimeType, pdfURL);
break;
}
case kPMDestinationPreview: {
// XXXjwatt Or should we use CocoaFileUtils::RevealFileInFinder(pdfURL);
AutoCFRelease<CFStringRef> pdfPath = CFURLCopyFileSystemPath(pdfURL, kCFURLPOSIXPathStyle);
AutoCFRelease<CFStringRef> pdfPath =
CFURLCopyFileSystemPath(pdfURL, kCFURLPOSIXPathStyle);
NSString* path = (NSString*)CFStringRef(pdfPath);
NSWorkspace* ws = [NSWorkspace sharedWorkspace];
[ws openFile:path];
@ -214,8 +226,8 @@ nsresult nsDeviceContextSpecX::DoEndDocument() {
}
case kPMDestinationFile: {
AutoCFRelease<CFURLRef> destURL(nullptr);
status =
::PMSessionCopyDestinationLocation(mPrintSession, mPMPrintSettings, destURL.receive());
status = ::PMSessionCopyDestinationLocation(
mPrintSession, mPMPrintSettings, destURL.receive());
if (status == noErr) {
AutoCFRelease<CFStringRef> sourcePathRef =
CFURLCopyFileSystemPath(pdfURL, kCFURLPOSIXPathStyle);
@ -234,12 +246,14 @@ nsresult nsDeviceContextSpecX::DoEndDocument() {
if ([fileManager fileExistsAtPath:sourcePath]) {
NSURL* src = static_cast<NSURL*>(CFURLRef(pdfURL));
NSURL* dest = static_cast<NSURL*>(CFURLRef(destURL));
bool ok = [fileManager replaceItemAtURL:dest
withItemAtURL:src
backupItemName:nil
options:NSFileManagerItemReplacementUsingNewMetadataOnly
resultingItemURL:nil
error:nil];
bool ok = [fileManager
replaceItemAtURL:dest
withItemAtURL:src
backupItemName:nil
options:
NSFileManagerItemReplacementUsingNewMetadataOnly
resultingItemURL:nil
error:nil];
if (!ok) {
return NS_ERROR_FAILURE;
}
@ -261,8 +275,8 @@ nsresult nsDeviceContextSpecX::DoEndDocument() {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft, double* aBottom,
double* aRight) {
void nsDeviceContextSpecX::GetPaperRect(double* aTop, double* aLeft,
double* aBottom, double* aRight) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
PMRect paperRect;
@ -286,7 +300,8 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget() {
#ifdef MOZ_ENABLE_SKIA_PDF
if (mPrintViaSkPDF) {
// TODO: Add support for stream printing via SkPDF if we enable that again.
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile));
nsresult rv =
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mTempFile));
NS_ENSURE_SUCCESS(rv, nullptr);
nsAutoCString tempPath("tmp-printing.pdf");
mTempFile->AppendNative(tempPath);
@ -298,6 +313,6 @@ already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget() {
}
#endif
return PrintTargetCG::CreateOrNull(mOutputStream, mPrintSession, mPageFormat, mPMPrintSettings,
size);
return PrintTargetCG::CreateOrNull(mOutputStream, mPrintSession, mPageFormat,
mPMPrintSettings, size);
}

Просмотреть файл

@ -49,24 +49,29 @@ nsDragService::nsDragService()
nsDragService::~nsDragService() {}
NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSIntRegion>& aRegion,
NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode,
const Maybe<CSSIntRegion>& aRegion,
NSPoint* aDragPoint) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mNativeDragView);
LayoutDeviceIntRect dragRect(0, 0, 20, 20);
NSImage* image = ConstructDragImage(mSourceNode, aRegion, mScreenPosition, &dragRect);
NSImage* image =
ConstructDragImage(mSourceNode, aRegion, mScreenPosition, &dragRect);
if (!image) {
// if no image was returned, just draw a rectangle
NSSize size;
size.width = nsCocoaUtils::DevPixelsToCocoaPoints(dragRect.width, scaleFactor);
size.height = nsCocoaUtils::DevPixelsToCocoaPoints(dragRect.height, scaleFactor);
size.width =
nsCocoaUtils::DevPixelsToCocoaPoints(dragRect.width, scaleFactor);
size.height =
nsCocoaUtils::DevPixelsToCocoaPoints(dragRect.height, scaleFactor);
image = [NSImage imageWithSize:size
flipped:YES
drawingHandler:^BOOL(NSRect dstRect) {
[[NSColor grayColor] set];
NSBezierPath* path = [NSBezierPath bezierPathWithRect:dstRect];
NSBezierPath* path =
[NSBezierPath bezierPathWithRect:dstRect];
[path setLineWidth:2.0];
[path stroke];
return YES;
@ -85,8 +90,10 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSIntRegion>& aRegion,
CSSIntPoint aPoint, LayoutDeviceIntRect* aDragRect) {
NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode,
const Maybe<CSSIntRegion>& aRegion,
CSSIntPoint aPoint,
LayoutDeviceIntRect* aDragRect) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mNativeDragView);
@ -97,8 +104,8 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
if (pc && (!aDragRect->width || !aDragRect->height)) {
// just use some suitable defaults
int32_t size = nsCocoaUtils::CocoaPointsToDevPixels(20, scaleFactor);
aDragRect->SetRect(pc->CSSPixelsToDevPixels(aPoint.x), pc->CSSPixelsToDevPixels(aPoint.y), size,
size);
aDragRect->SetRect(pc->CSSPixelsToDevPixels(aPoint.x),
pc->CSSPixelsToDevPixels(aPoint.y), size, size);
}
if (NS_FAILED(rv) || !surface) return nil;
@ -106,21 +113,23 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
uint32_t width = aDragRect->width;
uint32_t height = aDragRect->height;
RefPtr<DataSourceSurface> dataSurface =
Factory::CreateDataSourceSurface(IntSize(width, height), SurfaceFormat::B8G8R8A8);
RefPtr<DataSourceSurface> dataSurface = Factory::CreateDataSourceSurface(
IntSize(width, height), SurfaceFormat::B8G8R8A8);
DataSourceSurface::MappedSurface map;
if (!dataSurface->Map(DataSourceSurface::MapType::READ_WRITE, &map)) {
return nil;
}
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData(
BackendType::CAIRO, map.mData, dataSurface->GetSize(), map.mStride, dataSurface->GetFormat());
BackendType::CAIRO, map.mData, dataSurface->GetSize(), map.mStride,
dataSurface->GetFormat());
if (!dt) {
dataSurface->Unmap();
return nil;
}
dt->FillRect(gfx::Rect(0, 0, width, height), SurfacePattern(surface, ExtendMode::CLAMP),
dt->FillRect(gfx::Rect(0, 0, width, height),
SurfacePattern(surface, ExtendMode::CLAMP),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
NSBitmapImageRep* imageRep =
@ -140,7 +149,8 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
uint8_t* src = map.mData + i * map.mStride;
for (uint32_t j = 0; j < width; ++j) {
// Reduce transparency overall by multipying by a factor. Remember, Alpha
// is premultipled here. Also, Quartz likes RGBA, so do that translation as well.
// is premultipled here. Also, Quartz likes RGBA, so do that translation
// as well.
#ifdef IS_BIG_ENDIAN
dest[0] = uint8_t(src[1] * DRAG_TRANSLUCENCY);
dest[1] = uint8_t(src[2] * DRAG_TRANSLUCENCY);
@ -158,8 +168,8 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
}
dataSurface->Unmap();
NSImage* image =
[[NSImage alloc] initWithSize:NSMakeSize(width / scaleFactor, height / scaleFactor)];
NSImage* image = [[NSImage alloc]
initWithSize:NSMakeSize(width / scaleFactor, height / scaleFactor)];
[image addRepresentation:imageRep];
[imageRep release];
@ -168,9 +178,9 @@ NSImage* nsDragService::ConstructDragImage(nsINode* aDOMNode, const Maybe<CSSInt
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
const Maybe<CSSIntRegion>& aRegion,
uint32_t aActionType) {
nsresult nsDragService::InvokeDragSessionImpl(
nsIArray* aTransferableArray, const Maybe<CSSIntRegion>& aRegion,
uint32_t aActionType) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
#ifdef NIGHTLY_BUILD
@ -178,10 +188,11 @@ nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
#endif
if (!gLastDragView) {
// gLastDragView is non-null between -[ChildView mouseDown:] and -[ChildView mouseUp:].
// If we get here with gLastDragView being null, that means that the mouse button has already
// been released. In that case we need to abort the drag because the OS won't know where to drop
// whatever's being dragged, and we might end up with a stuck drag & drop session.
// gLastDragView is non-null between -[ChildView mouseDown:] and -[ChildView
// mouseUp:]. If we get here with gLastDragView being null, that means that
// the mouse button has already been released. In that case we need to abort
// the drag because the OS won't know where to drop whatever's being
// dragged, and we might end up with a stuck drag & drop session.
return NS_ERROR_FAILURE;
}
@ -205,7 +216,8 @@ nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
gDraggedTransferables->GetLength(&count);
for (uint32_t j = 0; j < count; j++) {
nsCOMPtr<nsITransferable> currentTransferable = do_QueryElementAt(aTransferableArray, j);
nsCOMPtr<nsITransferable> currentTransferable =
do_QueryElementAt(aTransferableArray, j);
if (!currentTransferable) {
return NS_ERROR_FAILURE;
}
@ -234,7 +246,8 @@ nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
localDragRect.origin.x = draggingPoint.x;
localDragRect.origin.y = draggingPoint.y - localDragRect.size.height;
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:pbItem];
NSDraggingItem* dragItem =
[[NSDraggingItem alloc] initWithPasteboardWriter:pbItem];
[pbItem release];
[dragItem setDraggingFrame:localDragRect contents:image];
@ -242,7 +255,8 @@ nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray,
nsBaseDragService::OpenDragPopup();
NSDraggingSession* draggingSession = [mNativeDragView
beginDraggingSessionWithItems:[NSArray arrayWithObject:[dragItem autorelease]]
beginDraggingSessionWithItems:[NSArray
arrayWithObject:[dragItem autorelease]]
event:mNativeDragEvent
source:mNativeDragView];
draggingSession.animatesToStartingPositionsOnCancelOrFail =
@ -261,24 +275,26 @@ nsDragService::GetData(nsITransferable* aTransferable, uint32_t aItemIndex) {
return NS_ERROR_FAILURE;
}
// get flavor list that includes all acceptable flavors (including ones obtained through
// conversion)
// get flavor list that includes all acceptable flavors (including ones
// obtained through conversion)
nsTArray<nsCString> flavors;
nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
// if this drag originated within Mozilla we should just use the cached data from
// when the drag started if possible
// if this drag originated within Mozilla we should just use the cached data
// from when the drag started if possible
if (mDataItems) {
nsCOMPtr<nsITransferable> currentTransferable = do_QueryElementAt(mDataItems, aItemIndex);
nsCOMPtr<nsITransferable> currentTransferable =
do_QueryElementAt(mDataItems, aItemIndex);
if (currentTransferable) {
for (uint32_t i = 0; i < flavors.Length(); i++) {
nsCString& flavorStr = flavors[i];
nsCOMPtr<nsISupports> dataSupports;
rv = currentTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(dataSupports));
rv = currentTransferable->GetTransferData(flavorStr.get(),
getter_AddRefs(dataSupports));
if (NS_SUCCEEDED(rv)) {
aTransferable->SetTransferData(flavorStr.get(), dataSupports);
return NS_OK; // maybe try to fill in more types? Is there a point?
@ -304,7 +320,8 @@ nsDragService::GetData(nsITransferable* aTransferable, uint32_t aItemIndex) {
// now check the actual clipboard for data
for (uint32_t i = 0; i < flavors.Length(); i++) {
nsCocoaUtils::SetTransferDataForTypeFromPasteboardItem(aTransferable, flavors[i], item);
nsCocoaUtils::SetTransferDataForTypeFromPasteboardItem(aTransferable,
flavors[i], item);
}
return NS_OK;
@ -327,7 +344,8 @@ nsDragService::IsDataFlavorSupported(const char* aDataFlavor, bool* _retval) {
uint32_t dataItemsCount;
mDataItems->GetLength(&dataItemsCount);
for (unsigned int i = 0; i < dataItemsCount; i++) {
nsCOMPtr<nsITransferable> currentTransferable = do_QueryElementAt(mDataItems, i);
nsCOMPtr<nsITransferable> currentTransferable =
do_QueryElementAt(mDataItems, i);
if (!currentTransferable) continue;
nsTArray<nsCString> flavors;
@ -352,7 +370,8 @@ nsDragService::IsDataFlavorSupported(const char* aDataFlavor, bool* _retval) {
type = [UTIHelper stringFromPboardType:NSPasteboardTypeString];
} else if (dataFlavor.EqualsLiteral(kHTMLMime)) {
type = [UTIHelper stringFromPboardType:NSPasteboardTypeHTML];
} else if (dataFlavor.EqualsLiteral(kURLMime) || dataFlavor.EqualsLiteral(kURLDataMime)) {
} else if (dataFlavor.EqualsLiteral(kURLMime) ||
dataFlavor.EqualsLiteral(kURLDataMime)) {
type = [UTIHelper stringFromPboardType:kPublicUrlPboardType];
} else if (dataFlavor.EqualsLiteral(kURLDescriptionMime)) {
type = [UTIHelper stringFromPboardType:kPublicUrlNamePboardType];
@ -362,9 +381,10 @@ nsDragService::IsDataFlavorSupported(const char* aDataFlavor, bool* _retval) {
type = [UTIHelper stringFromPboardType:kMozCustomTypesPboardType];
}
NSString* availableType =
[globalDragPboard availableTypeFromArray:[NSArray arrayWithObjects:(id)type, nil]];
if (availableType && nsCocoaUtils::IsValidPasteboardType(availableType, allowFileURL)) {
NSString* availableType = [globalDragPboard
availableTypeFromArray:[NSArray arrayWithObjects:(id)type, nil]];
if (availableType &&
nsCocoaUtils::IsValidPasteboardType(availableType, allowFileURL)) {
*_retval = true;
}
@ -396,19 +416,22 @@ nsDragService::GetNumDropItems(uint32_t* aNumItems) {
}
NS_IMETHODIMP
nsDragService::UpdateDragImage(nsINode* aImage, int32_t aImageX, int32_t aImageY) {
nsDragService::UpdateDragImage(nsINode* aImage, int32_t aImageX,
int32_t aImageY) {
nsBaseDragService::UpdateDragImage(aImage, aImageX, aImageY);
mDragImageChanged = true;
return NS_OK;
}
void nsDragService::DragMovedWithView(NSDraggingSession* aSession, NSPoint aPoint) {
void nsDragService::DragMovedWithView(NSDraggingSession* aSession,
NSPoint aPoint) {
aPoint.y = nsCocoaUtils::FlippedScreenY(aPoint.y);
// XXX It feels like we should be using the backing scale factor at aPoint
// rather than the initial drag view, but I've seen no ill effects of this.
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mNativeDragView);
LayoutDeviceIntPoint devPoint = nsCocoaUtils::CocoaPointsToDevPixels(aPoint, scaleFactor);
LayoutDeviceIntPoint devPoint =
nsCocoaUtils::CocoaPointsToDevPixels(aPoint, scaleFactor);
// If the image has changed, call enumerateDraggingItemsWithOptions to get
// the item being dragged and update its image.
@ -422,32 +445,39 @@ void nsDragService::DragMovedWithView(NSDraggingSession* aSession, NSPoint aPoin
}
if (pc) {
void (^changeImageBlock)(NSDraggingItem*, NSInteger, BOOL*) =
^(NSDraggingItem* draggingItem, NSInteger idx, BOOL* stop) {
// We never add more than one item right now, but check just in case.
if (idx > 0) {
return;
}
void (^changeImageBlock)(NSDraggingItem*, NSInteger, BOOL*) = ^(
NSDraggingItem* draggingItem, NSInteger idx, BOOL* stop) {
// We never add more than one item right now, but check just in case.
if (idx > 0) {
return;
}
nsPoint pt =
LayoutDevicePixel::ToAppUnits(devPoint, pc->DeviceContext()->AppUnitsPerDevPixel());
CSSIntPoint screenPoint = CSSIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
nsPoint pt = LayoutDevicePixel::ToAppUnits(
devPoint, pc->DeviceContext()->AppUnitsPerDevPixel());
CSSIntPoint screenPoint =
CSSIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
// Create a new image; if one isn't returned don't change the current one.
LayoutDeviceIntRect newRect;
NSImage* image = ConstructDragImage(mSourceNode, Nothing(), screenPoint, &newRect);
if (image) {
NSRect draggingRect = nsCocoaUtils::GeckoRectToCocoaRectDevPix(newRect, scaleFactor);
[draggingItem setDraggingFrame:draggingRect contents:image];
}
};
// Create a new image; if one isn't returned don't change the current
// one.
LayoutDeviceIntRect newRect;
NSImage* image =
ConstructDragImage(mSourceNode, Nothing(), screenPoint, &newRect);
if (image) {
NSRect draggingRect =
nsCocoaUtils::GeckoRectToCocoaRectDevPix(newRect, scaleFactor);
[draggingItem setDraggingFrame:draggingRect contents:image];
}
};
[aSession enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:nil
classes:[NSArray arrayWithObject:[NSPasteboardItem class]]
searchOptions:@{}
usingBlock:changeImageBlock];
[aSession
enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:nil
classes:[NSArray
arrayWithObject:
[NSPasteboardItem class]]
searchOptions:@{}
usingBlock:changeImageBlock];
}
}

Просмотреть файл

@ -59,9 +59,11 @@ static void SetShowHiddenFileState(NSSavePanel* panel) {
if (gCallSecretHiddenFileAPI) {
// invoke a method to get a Cocoa-internal nav view
SEL navViewSelector = @selector(_navView);
NSMethodSignature* navViewSignature = [panel methodSignatureForSelector:navViewSelector];
NSMethodSignature* navViewSignature =
[panel methodSignatureForSelector:navViewSelector];
if (!navViewSignature) return;
NSInvocation* navViewInvocation = [NSInvocation invocationWithMethodSignature:navViewSignature];
NSInvocation* navViewInvocation =
[NSInvocation invocationWithMethodSignature:navViewSignature];
[navViewInvocation setSelector:navViewSelector];
[navViewInvocation setTarget:panel];
[navViewInvocation invoke];
@ -90,27 +92,32 @@ nsFilePicker::nsFilePicker() : mSelectedTypeIndex(0) {}
nsFilePicker::~nsFilePicker() {}
void nsFilePicker::InitNative(nsIWidget* aParent, const nsAString& aTitle) { mTitle = aTitle; }
void nsFilePicker::InitNative(nsIWidget* aParent, const nsAString& aTitle) {
mTitle = aTitle;
}
NSView* nsFilePicker::GetAccessoryView() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSView* accessoryView = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)] autorelease];
NSView* accessoryView =
[[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)] autorelease];
// Set a label's default value.
NSString* label = @"Format:";
// Try to get the localized string.
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
nsCOMPtr<nsIStringBundleService> sbs =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
nsCOMPtr<nsIStringBundle> bundle;
nsresult rv =
sbs->CreateBundle("chrome://global/locale/filepicker.properties", getter_AddRefs(bundle));
nsresult rv = sbs->CreateBundle(
"chrome://global/locale/filepicker.properties", getter_AddRefs(bundle));
if (NS_SUCCEEDED(rv)) {
nsAutoString locaLabel;
rv = bundle->GetStringFromName("formatLabel", locaLabel);
if (NS_SUCCEEDED(rv)) {
label = [NSString stringWithCharacters:reinterpret_cast<const unichar*>(locaLabel.get())
length:locaLabel.Length()];
label = [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(locaLabel.get())
length:locaLabel.Length()];
}
}
@ -127,8 +134,9 @@ NSView* nsFilePicker::GetAccessoryView() {
[textField sizeToFit];
// set up popup button
NSPopUpButton* popupButton = [[[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)
pullsDown:NO] autorelease];
NSPopUpButton* popupButton =
[[[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)
pullsDown:NO] autorelease];
uint32_t numMenuItems = mTitles.Length();
for (uint32_t i = 0; i < numMenuItems; i++) {
const nsString& currentTitle = mTitles[i];
@ -136,11 +144,13 @@ NSView* nsFilePicker::GetAccessoryView() {
if (currentTitle.IsEmpty()) {
const nsString& currentFilter = mFilters[i];
titleString =
[[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(currentFilter.get())
[[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(
currentFilter.get())
length:currentFilter.Length()];
} else {
titleString =
[[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(currentTitle.get())
[[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(
currentTitle.get())
length:currentTitle.Length()];
}
[popupButton addItemWithTitle:titleString];
@ -149,28 +159,34 @@ NSView* nsFilePicker::GetAccessoryView() {
if (mSelectedTypeIndex >= 0 && (uint32_t)mSelectedTypeIndex < numMenuItems)
[popupButton selectItemAtIndex:mSelectedTypeIndex];
[popupButton setTag:kSaveTypeControlTag];
[popupButton sizeToFit]; // we have to do sizeToFit to get the height calculated for us
// This is just a default width that works well, doesn't truncate the vast majority of
// things that might end up in the menu.
[popupButton sizeToFit]; // we have to do sizeToFit to get the height
// calculated for us
// This is just a default width that works well, doesn't truncate the vast
// majority of things that might end up in the menu.
[popupButton setFrameSize:NSMakeSize(180, [popupButton frame].size.height)];
// position everything based on control sizes with kAccessoryViewPadding pix padding
// on each side kAccessoryViewPadding pix horizontal padding between controls
// position everything based on control sizes with kAccessoryViewPadding pix
// padding on each side kAccessoryViewPadding pix horizontal padding between
// controls
float greatestHeight = [textField frame].size.height;
if ([popupButton frame].size.height > greatestHeight)
greatestHeight = [popupButton frame].size.height;
float totalViewHeight = greatestHeight + kAccessoryViewPadding * 2;
float totalViewWidth =
[textField frame].size.width + [popupButton frame].size.width + kAccessoryViewPadding * 3;
float totalViewWidth = [textField frame].size.width +
[popupButton frame].size.width +
kAccessoryViewPadding * 3;
[accessoryView setFrameSize:NSMakeSize(totalViewWidth, totalViewHeight)];
float textFieldOriginY =
((greatestHeight - [textField frame].size.height) / 2 + 1) + kAccessoryViewPadding;
[textField setFrameOrigin:NSMakePoint(kAccessoryViewPadding, textFieldOriginY)];
((greatestHeight - [textField frame].size.height) / 2 + 1) +
kAccessoryViewPadding;
[textField
setFrameOrigin:NSMakePoint(kAccessoryViewPadding, textFieldOriginY)];
float popupOriginX = [textField frame].size.width + kAccessoryViewPadding * 2;
float popupOriginY =
((greatestHeight - [popupButton frame].size.height) / 2) + kAccessoryViewPadding;
((greatestHeight - [popupButton frame].size.height) / 2) +
kAccessoryViewPadding;
[popupButton setFrameOrigin:NSMakePoint(popupOriginX, popupOriginY)];
[accessoryView addSubview:textField];
@ -255,9 +271,10 @@ static void UpdatePanelFileTypes(NSOpenPanel* aPanel, NSArray* aFilters) {
}
@end
// Use OpenPanel to do a GetFile. Returns |returnOK| if the user presses OK in the dialog.
nsIFilePicker::ResultCode nsFilePicker::GetLocalFiles(bool inAllowMultiple,
nsCOMArray<nsIFile>& outFiles) {
// Use OpenPanel to do a GetFile. Returns |returnOK| if the user presses OK in
// the dialog.
nsIFilePicker::ResultCode nsFilePicker::GetLocalFiles(
bool inAllowMultiple, nsCOMArray<nsIFile>& outFiles) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
ResultCode retVal = nsIFilePicker::returnCancel;
@ -308,10 +325,11 @@ nsIFilePicker::ResultCode nsFilePicker::GetLocalFiles(bool inAllowMultiple,
[observer setOpenPanel:thePanel];
[observer setFilePicker:this];
[[NSNotificationCenter defaultCenter] addObserver:observer
selector:@selector(menuChangedItem:)
name:NSMenuWillSendActionNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:observer
selector:@selector(menuChangedItem:)
name:NSMenuWillSendActionNotification
object:nil];
UpdatePanelFileTypes(thePanel, filters);
result = [thePanel runModal];
@ -343,7 +361,8 @@ nsIFilePicker::ResultCode nsFilePicker::GetLocalFiles(bool inAllowMultiple,
nsCOMPtr<nsIFile> localFile;
NS_NewLocalFile(u""_ns, true, getter_AddRefs(localFile));
nsCOMPtr<nsILocalFileMac> macLocalFile = do_QueryInterface(localFile);
if (macLocalFile && NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)url))) {
if (macLocalFile &&
NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)url))) {
outFiles.AppendObject(localFile);
}
}
@ -355,10 +374,13 @@ nsIFilePicker::ResultCode nsFilePicker::GetLocalFiles(bool inAllowMultiple,
NS_OBJC_END_TRY_BLOCK_RETURN(nsIFilePicker::returnOK);
}
// Use OpenPanel to do a GetFolder. Returns |returnOK| if the user presses OK in the dialog.
// Use OpenPanel to do a GetFolder. Returns |returnOK| if the user presses OK in
// the dialog.
nsIFilePicker::ResultCode nsFilePicker::GetLocalFolder(nsIFile** outFile) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NS_ASSERTION(outFile, "this protected member function expects a null initialized out pointer");
NS_ASSERTION(
outFile,
"this protected member function expects a null initialized out pointer");
ResultCode retVal = nsIFilePicker::returnCancel;
NSOpenPanel* thePanel = [NSOpenPanel openPanel];
@ -394,7 +416,8 @@ nsIFilePicker::ResultCode nsFilePicker::GetLocalFolder(nsIFile** outFile) {
nsCOMPtr<nsIFile> localFile;
NS_NewLocalFile(u""_ns, true, getter_AddRefs(localFile));
nsCOMPtr<nsILocalFileMac> macLocalFile = do_QueryInterface(localFile);
if (macLocalFile && NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)theURL))) {
if (macLocalFile &&
NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)theURL))) {
*outFile = localFile;
NS_ADDREF(*outFile);
retVal = returnOK;
@ -409,7 +432,9 @@ nsIFilePicker::ResultCode nsFilePicker::GetLocalFolder(nsIFile** outFile) {
// Returns |returnOK| if the user presses OK in the dialog.
nsIFilePicker::ResultCode nsFilePicker::PutLocalFile(nsIFile** outFile) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NS_ASSERTION(outFile, "this protected member function expects a null initialized out pointer");
NS_ASSERTION(
outFile,
"this protected member function expects a null initialized out pointer");
ResultCode retVal = nsIFilePicker::returnCancel;
NSSavePanel* thePanel = [NSSavePanel savePanel];
@ -423,8 +448,9 @@ nsIFilePicker::ResultCode nsFilePicker::PutLocalFile(nsIFile** outFile) {
[thePanel setAccessoryView:accessoryView];
// set up default file name
NSString* defaultFilename = [NSString stringWithCharacters:(const unichar*)mDefaultFilename.get()
length:mDefaultFilename.Length()];
NSString* defaultFilename =
[NSString stringWithCharacters:(const unichar*)mDefaultFilename.get()
length:mDefaultFilename.Length()];
// Set up the allowed type. This prevents the extension from being selected.
NSString* extension = defaultFilename.pathExtension;
@ -440,12 +466,13 @@ nsIFilePicker::ResultCode nsFilePicker::PutLocalFile(nsIFile** outFile) {
// trying to add a non-default extension. To avoid the confusion, we ensure
// that all extensions are shown in the panel if the remaining extension is
// known by the OS.
NSString* fileName = [[defaultFilename lastPathComponent] stringByDeletingPathExtension];
NSString* fileName =
[[defaultFilename lastPathComponent] stringByDeletingPathExtension];
NSString* otherExtension = fileName.pathExtension;
if (otherExtension.length != 0) {
// There's another extension here. Get the UTI.
CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
(CFStringRef)otherExtension, NULL);
CFStringRef type = UTTypeCreatePreferredIdentifierForTag(
kUTTagClassFilenameExtension, (CFStringRef)otherExtension, NULL);
if (type) {
if (!CFStringHasPrefix(type, CFSTR("dyn."))) {
// We have a UTI, otherwise the type would have a "dyn." prefix. Ensure
@ -480,11 +507,13 @@ nsIFilePicker::ResultCode nsFilePicker::PutLocalFile(nsIFile** outFile) {
nsCOMPtr<nsIFile> localFile;
NS_NewLocalFile(u""_ns, true, getter_AddRefs(localFile));
nsCOMPtr<nsILocalFileMac> macLocalFile = do_QueryInterface(localFile);
if (macLocalFile && NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)fileURL))) {
if (macLocalFile &&
NS_SUCCEEDED(macLocalFile->InitWithCFURL((CFURLRef)fileURL))) {
*outFile = localFile;
NS_ADDREF(*outFile);
// We tell if we are replacing or not by just looking to see if the file exists.
// The user could not have hit OK and not meant to replace the file.
// We tell if we are replacing or not by just looking to see if the file
// exists. The user could not have hit OK and not meant to replace the
// file.
if ([[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]])
retVal = returnReplace;
else
@ -505,7 +534,8 @@ NSArray* nsFilePicker::GetFilterList() {
}
if (mFilters.Length() <= (uint32_t)mSelectedTypeIndex) {
NS_WARNING("An out of range index has been selected. Using the first index instead.");
NS_WARNING("An out of range index has been selected. Using the first index "
"instead.");
mSelectedTypeIndex = 0;
}
@ -522,17 +552,21 @@ NSArray* nsFilePicker::GetFilterList() {
// in the format "ext" by NSOpenPanel. So we need to filter some characters.
NSMutableString* filterString = [[[NSMutableString alloc]
initWithString:[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(filterWide.get())
length:filterWide.Length()]] autorelease];
NSCharacterSet* set = [NSCharacterSet characterSetWithCharactersInString:@". *"];
stringWithCharacters:reinterpret_cast<const unichar*>(
filterWide.get())
length:filterWide.Length()]]
autorelease];
NSCharacterSet* set =
[NSCharacterSet characterSetWithCharactersInString:@". *"];
NSRange range = [filterString rangeOfCharacterFromSet:set];
while (range.length) {
[filterString replaceCharactersInRange:range withString:@""];
range = [filterString rangeOfCharacterFromSet:set];
}
return
[[[NSArray alloc] initWithArray:[filterString componentsSeparatedByString:@";"]] autorelease];
return [[[NSArray alloc]
initWithArray:[filterString componentsSeparatedByString:@";"]]
autorelease];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
@ -546,8 +580,10 @@ void nsFilePicker::SetDialogTitle(const nsString& inTitle, id aPanel) {
length:inTitle.Length()]];
if (!mOkButtonLabel.IsEmpty()) {
[aPanel setPrompt:[NSString stringWithCharacters:(const unichar*)mOkButtonLabel.get()
length:mOkButtonLabel.Length()]];
[aPanel
setPrompt:[NSString
stringWithCharacters:(const unichar*)mOkButtonLabel.get()
length:mOkButtonLabel.Length()]];
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
@ -562,9 +598,9 @@ NSString* nsFilePicker::PanelDefaultDirectory() {
if (mDisplayDirectory) {
nsAutoString pathStr;
mDisplayDirectory->GetPath(pathStr);
directory =
[[[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(pathStr.get())
length:pathStr.Length()] autorelease];
directory = [[[NSString alloc]
initWithCharacters:reinterpret_cast<const unichar*>(pathStr.get())
length:pathStr.Length()] autorelease];
}
return directory;
@ -602,7 +638,9 @@ NS_IMETHODIMP nsFilePicker::SetDefaultString(const nsAString& aString) {
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString& aString) { return NS_ERROR_FAILURE; }
NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString& aString) {
return NS_ERROR_FAILURE;
}
// The default extension to use for files
NS_IMETHODIMP nsFilePicker::GetDefaultExtension(nsAString& aExtension) {
@ -610,7 +648,9 @@ NS_IMETHODIMP nsFilePicker::GetDefaultExtension(nsAString& aExtension) {
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString& aExtension) { return NS_OK; }
NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString& aExtension) {
return NS_OK;
}
// Append an entry to the filters array
NS_IMETHODIMP

Просмотреть файл

@ -47,18 +47,22 @@ void nsLookAndFeel::NativeInit() {
}
static nscolor GetColorFromNSColor(NSColor* aColor) {
NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
NSColor* deviceColor =
[aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
return NS_RGBA((unsigned int)(deviceColor.redComponent * 255.0),
(unsigned int)(deviceColor.greenComponent * 255.0),
(unsigned int)(deviceColor.blueComponent * 255.0),
(unsigned int)(deviceColor.alphaComponent * 255.0));
}
static nscolor GetColorFromNSColorWithCustomAlpha(NSColor* aColor, float alpha) {
NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
static nscolor GetColorFromNSColorWithCustomAlpha(NSColor* aColor,
float alpha) {
NSColor* deviceColor =
[aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
return NS_RGBA((unsigned int)(deviceColor.redComponent * 255.0),
(unsigned int)(deviceColor.greenComponent * 255.0),
(unsigned int)(deviceColor.blueComponent * 255.0), (unsigned int)(alpha * 255.0));
(unsigned int)(deviceColor.blueComponent * 255.0),
(unsigned int)(alpha * 255.0));
}
// Turns an opaque selection color into a partially transparent selection color,
@ -74,11 +78,12 @@ static nscolor GetColorFromNSColorWithCustomAlpha(NSColor* aColor, float alpha)
// whereas white text on dark blue (which what you get if you mix
// partially-transparent light blue with the black textbox background) has much
// better contrast.
nscolor nsLookAndFeel::ProcessSelectionBackground(nscolor aColor, ColorScheme aScheme) {
nscolor nsLookAndFeel::ProcessSelectionBackground(nscolor aColor,
ColorScheme aScheme) {
if (aScheme == ColorScheme::Dark) {
// When we use a dark selection color, we do not change alpha because we do
// not use dark selection in content. The dark system color is appropriate for
// Firefox UI without needing to adjust its alpha.
// not use dark selection in content. The dark system color is appropriate
// for Firefox UI without needing to adjust its alpha.
return aColor;
}
uint16_t hue, sat, value;
@ -100,7 +105,8 @@ nscolor nsLookAndFeel::ProcessSelectionBackground(nscolor aColor, ColorScheme aS
return resultColor;
}
nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor& aColor) {
nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
nscolor& aColor) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK
NSAppearance.currentAppearance = NSAppearanceForColorScheme(aScheme);
@ -108,18 +114,19 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
nscolor color = 0;
switch (aID) {
case ColorID::Infobackground:
color = aScheme == ColorScheme::Light ? NS_RGB(0xdd, 0xdd, 0xdd)
: GetColorFromNSColor(NSColor.windowBackgroundColor);
color = aScheme == ColorScheme::Light
? NS_RGB(0xdd, 0xdd, 0xdd)
: GetColorFromNSColor(NSColor.windowBackgroundColor);
break;
case ColorID::Highlight:
color = ProcessSelectionBackground(GetColorFromNSColor(NSColor.selectedTextBackgroundColor),
aScheme);
color = ProcessSelectionBackground(
GetColorFromNSColor(NSColor.selectedTextBackgroundColor), aScheme);
break;
// This is used to gray out the selection when it's not focused. Used with
// nsISelectionController::SELECTION_DISABLED.
case ColorID::TextSelectDisabledBackground:
color = ProcessSelectionBackground(GetColorFromNSColor(NSColor.secondarySelectedControlColor),
aScheme);
color = ProcessSelectionBackground(
GetColorFromNSColor(NSColor.secondarySelectedControlColor), aScheme);
break;
case ColorID::MozMenuhoverdisabled:
aColor = NS_TRANSPARENT;
@ -158,23 +165,26 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
//
// css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
//
// It's really hard to effectively map these to the Appearance Manager properly,
// since they are modeled word for word after the win32 system colors and don't have any
// real counterparts in the Mac world. I'm sure we'll be tweaking these for
// years to come.
// It's really hard to effectively map these to the Appearance Manager
// properly, since they are modeled word for word after the win32 system
// colors and don't have any real counterparts in the Mac world. I'm sure
// we'll be tweaking these for years to come.
//
// Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that form the defaults
// Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that
// form the defaults
// if querying the Appearance Manager fails ;)
//
case ColorID::MozMacDefaultbuttontext:
color = NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::MozButtonactivetext:
// Pre-macOS 12, pressed buttons were filled with the highlight color and the text was white.
// Starting with macOS 12, pressed (non-default) buttons are filled with medium gray and the
// text color is the same as in the non-pressed state.
color = nsCocoaFeatures::OnMontereyOrLater() ? GetColorFromNSColor(NSColor.controlTextColor)
: NS_RGB(0xFF, 0xFF, 0xFF);
// Pre-macOS 12, pressed buttons were filled with the highlight color and
// the text was white. Starting with macOS 12, pressed (non-default)
// buttons are filled with medium gray and the text color is the same as
// in the non-pressed state.
color = nsCocoaFeatures::OnMontereyOrLater()
? GetColorFromNSColor(NSColor.controlTextColor)
: NS_RGB(0xFF, 0xFF, 0xFF);
break;
case ColorID::Menutext:
case ColorID::Infotext:
@ -209,18 +219,22 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
break;
case ColorID::Buttonshadow:
case ColorID::Threeddarkshadow:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID) : NS_RGB(0xDC, 0xDC, 0xDC);
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xDC, 0xDC, 0xDC);
break;
case ColorID::Threedshadow:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID) : NS_RGB(0xE0, 0xE0, 0xE0);
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xE0, 0xE0, 0xE0);
break;
case ColorID::Threedface:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID) : NS_RGB(0xF0, 0xF0, 0xF0);
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xF0, 0xF0, 0xF0);
break;
case ColorID::Threedlightshadow:
case ColorID::Buttonborder:
case ColorID::MozDisabledfield:
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID) : NS_RGB(0xDA, 0xDA, 0xDA);
color = aScheme == ColorScheme::Dark ? *GenericDarkColor(aID)
: NS_RGB(0xDA, 0xDA, 0xDA);
break;
case ColorID::Menu:
color = GetColorFromNSColor(NSColor.textBackgroundColor);
@ -248,7 +262,8 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
color = GetColorFromNSColor(NSColor.controlTextColor);
break;
case ColorID::MozMacFocusring:
color = GetColorFromNSColorWithCustomAlpha(NSColor.keyboardFocusIndicatorColor, 0.48);
color = GetColorFromNSColorWithCustomAlpha(
NSColor.keyboardFocusIndicatorColor, 0.48);
break;
case ColorID::MozMacMenutextdisable:
color = NS_RGB(0x98, 0x98, 0x98);
@ -266,11 +281,13 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
break;
case ColorID::MozEventreerow:
// Background color of even list rows.
color = GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[0]);
color =
GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[0]);
break;
case ColorID::MozOddtreerow:
// Background color of odd list rows.
color = GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[1]);
color =
GetColorFromNSColor(NSColor.controlAlternatingRowBackgroundColors[1]);
break;
case ColorID::MozNativehyperlinktext:
color = GetColorFromNSColor(NSColor.linkColor);
@ -281,13 +298,16 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
case ColorID::MozMacTooltip:
case ColorID::MozMacMenupopup:
case ColorID::MozMacMenuitem:
color = aScheme == ColorScheme::Light ? NS_RGB(0xf6, 0xf6, 0xf6) : NS_RGB(0x28, 0x28, 0x28);
color = aScheme == ColorScheme::Light ? NS_RGB(0xf6, 0xf6, 0xf6)
: NS_RGB(0x28, 0x28, 0x28);
break;
case ColorID::MozMacSourceList:
color = aScheme == ColorScheme::Light ? NS_RGB(0xf6, 0xf6, 0xf6) : NS_RGB(0x2d, 0x2d, 0x2d);
color = aScheme == ColorScheme::Light ? NS_RGB(0xf6, 0xf6, 0xf6)
: NS_RGB(0x2d, 0x2d, 0x2d);
break;
case ColorID::MozMacSourceListSelection:
color = aScheme == ColorScheme::Light ? NS_RGB(0xd3, 0xd3, 0xd3) : NS_RGB(0x2d, 0x2d, 0x2d);
color = aScheme == ColorScheme::Light ? NS_RGB(0xd3, 0xd3, 0xd3)
: NS_RGB(0x2d, 0x2d, 0x2d);
break;
case ColorID::MozMacActiveMenuitem:
case ColorID::MozMacActiveSourceListSelection:
@ -298,7 +318,8 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme, nscolor
case ColorID::Inactivecaption:
case ColorID::Activecaption: {
if (aScheme == ColorScheme::Light &&
NSWorkspace.sharedWorkspace.accessibilityDisplayShouldIncreaseContrast) {
NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldIncreaseContrast) {
// This has better contrast than the stand-in colors.
aColor = GetColorFromNSColor(NSColor.windowBackgroundColor);
return NS_OK;
@ -410,11 +431,13 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
aResult = NS_ALERT_TOP;
break;
case IntID::TabFocusModel:
aResult = [NSApp isFullKeyboardAccessEnabled] ? nsIContent::eTabFocus_any
: nsIContent::eTabFocus_textControlsMask;
aResult = [NSApp isFullKeyboardAccessEnabled]
? nsIContent::eTabFocus_any
: nsIContent::eTabFocus_textControlsMask;
break;
case IntID::ScrollToClick: {
aResult = [[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"];
aResult = [[NSUserDefaults standardUserDefaults]
boolForKey:@"AppleScrollerPagingBehavior"];
} break;
case IntID::ChosenMenuItemsShouldBlink:
aResult = 1;
@ -444,19 +467,24 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
aResult = SystemWantsDarkTheme();
break;
case IntID::PrefersReducedMotion:
aResult = NSWorkspace.sharedWorkspace.accessibilityDisplayShouldReduceMotion;
aResult =
NSWorkspace.sharedWorkspace.accessibilityDisplayShouldReduceMotion;
break;
case IntID::PrefersReducedTransparency:
aResult = NSWorkspace.sharedWorkspace.accessibilityDisplayShouldReduceTransparency;
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldReduceTransparency;
break;
case IntID::InvertedColors:
aResult = NSWorkspace.sharedWorkspace.accessibilityDisplayShouldInvertColors;
aResult =
NSWorkspace.sharedWorkspace.accessibilityDisplayShouldInvertColors;
break;
case IntID::UseAccessibilityTheme:
aResult = NSWorkspace.sharedWorkspace.accessibilityDisplayShouldIncreaseContrast;
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldIncreaseContrast;
break;
case IntID::VideoDynamicRange: {
// If the platform says it supports HDR, then we claim to support video-dynamic-range.
// If the platform says it supports HDR, then we claim to support
// video-dynamic-range.
gfxPlatform* platform = gfxPlatform::GetPlatform();
MOZ_ASSERT(platform);
aResult = platform->SupportsHDR();
@ -487,7 +515,8 @@ nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
aResult = 2.0f;
break;
case FloatID::CursorScale: {
id uaDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.universalaccess"];
id uaDefaults = [[NSUserDefaults alloc]
initWithSuiteName:@"com.apple.universalaccess"];
float f = [uaDefaults floatForKey:@"mouseDriverCursorSize"];
[uaDefaults release];
aResult = f > 0.0 ? f : 1.0; // default to 1.0 if value not available
@ -504,24 +533,29 @@ nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
}
bool nsLookAndFeel::SystemWantsDarkTheme() {
// This returns true if the macOS system appearance is set to dark mode, false otherwise.
NSAppearanceName aquaOrDarkAqua = [NSApp.effectiveAppearance
bestMatchFromAppearancesWithNames:@[ NSAppearanceNameAqua, NSAppearanceNameDarkAqua ]];
// This returns true if the macOS system appearance is set to dark mode, false
// otherwise.
NSAppearanceName aquaOrDarkAqua =
[NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua, NSAppearanceNameDarkAqua
]];
return [aquaOrDarkAqua isEqualToString:NSAppearanceNameDarkAqua];
}
/*static*/
bool nsLookAndFeel::IsSystemOrientationRTL() {
NSWindow* window = [[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSWindowStyleMaskBorderless
backing:NSBackingStoreBuffered
defer:NO];
NSWindow* window =
[[NSWindow alloc] initWithContentRect:NSZeroRect
styleMask:NSWindowStyleMaskBorderless
backing:NSBackingStoreBuffered
defer:NO];
auto direction = window.windowTitlebarLayoutDirection;
[window release];
return direction == NSUserInterfaceLayoutDirectionRightToLeft;
}
bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName, gfxFontStyle& aFontStyle) {
bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsAutoCString name;
@ -535,8 +569,10 @@ bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName, gfxFontStyle&
void nsLookAndFeel::RecordAccessibilityTelemetry() {
if ([[NSWorkspace sharedWorkspace]
respondsToSelector:@selector(accessibilityDisplayShouldInvertColors)]) {
bool val = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
respondsToSelector:@selector
(accessibilityDisplayShouldInvertColors)]) {
bool val =
[[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
Telemetry::ScalarSet(Telemetry::ScalarID::A11Y_INVERT_COLORS, val);
}
}
@ -553,14 +589,16 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
- (instancetype)init {
self = [super init];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(colorsChanged)
name:NSControlTintDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(colorsChanged)
name:NSSystemColorsDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(colorsChanged)
name:NSControlTintDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(colorsChanged)
name:NSSystemColorsDidChangeNotification
object:nil];
[NSWorkspace.sharedWorkspace.notificationCenter
addObserver:self
@ -568,10 +606,11 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(scrollbarsChanged)
name:NSPreferredScrollerStyleDidChangeNotification
object:nil];
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(scrollbarsChanged)
name:NSPreferredScrollerStyleDidChangeNotification
object:nil];
[NSDistributedNotificationCenter.defaultCenter
addObserver:self
selector:@selector(scrollbarsChanged)
@ -595,7 +634,10 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
forKeyPath:@"effectiveAppearance"
options:0
context:nil];
[NSApp addObserver:self forKeyPath:@"effectiveAppearance" options:0 context:nil];
[NSApp addObserver:self
forKeyPath:@"effectiveAppearance"
options:0
context:nil];
return self;
}
@ -607,7 +649,10 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
if ([keyPath isEqualToString:@"effectiveAppearance"]) {
[self entireThemeChanged];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
@ -620,11 +665,12 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
}
- (void)mediaQueriesChanged {
// Changing`Invert Colors` sends AccessibilityDisplayOptionsDidChangeNotifications.
// We monitor that setting via telemetry, so call into that
// recording method here.
// Changing`Invert Colors` sends
// AccessibilityDisplayOptionsDidChangeNotifications. We monitor that setting
// via telemetry, so call into that recording method here.
nsLookAndFeel::RecordAccessibilityTelemetry();
LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::MediaQueriesOnly);
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
}
- (void)colorsChanged {
@ -632,9 +678,12 @@ void nsLookAndFeel::RecordAccessibilityTelemetry() {
}
- (void)cachedValuesChanged {
// We only need to re-cache (and broadcast) updated LookAndFeel values, so that they're
// up-to-date the next time they're queried. No further change handling is needed.
// TODO: Add a change hint for this which avoids the unnecessary media query invalidation.
LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind::MediaQueriesOnly);
// We only need to re-cache (and broadcast) updated LookAndFeel values, so
// that they're up-to-date the next time they're queried. No further change
// handling is needed.
// TODO: Add a change hint for this which avoids the unnecessary media query
// invalidation.
LookAndFeel::NotifyChangedAllWindows(
widget::ThemeChangeKind::MediaQueriesOnly);
}
@end

Просмотреть файл

@ -12,9 +12,9 @@
/*! @category nsMacCursor (PrivateMethods)
@abstract Private methods internal to the nsMacCursor class.
@discussion <code>nsMacCursor</code> is effectively an abstract class. It does not define
complete behaviour in and of itself, the subclasses defined in this file provide the useful
implementations.
@discussion <code>nsMacCursor</code> is effectively an abstract class. It
does not define complete behaviour in and of itself, the subclasses defined
in this file provide the useful implementations.
*/
@interface nsMacCursor (PrivateMethods)
@ -27,56 +27,62 @@
/*! @method numFrames
@abstract Query the number of frames in this cursor's animation.
@discussion Returns the number of frames in this cursor's animation. Static cursors return 1.
@discussion Returns the number of frames in this cursor's animation. Static
cursors return 1.
*/
- (int)numFrames;
/*! @method createTimer
@abstract Create a Timer to use to animate the cursor.
@discussion Creates an instance of <code>NSTimer</code> which is used to drive the cursor
animation. This method should only be called for cursors that are animated.
@discussion Creates an instance of <code>NSTimer</code> which is used to
drive the cursor animation. This method should only be called for cursors
that are animated.
*/
- (void)createTimer;
/*! @method destroyTimer
@abstract Destroy any timer instance associated with this cursor.
@discussion Invalidates and releases any <code>NSTimer</code> instance associated with this
cursor.
@discussion Invalidates and releases any <code>NSTimer</code> instance
associated with this cursor.
*/
- (void)destroyTimer;
/*! @method destroyTimer
@abstract Destroy any timer instance associated with this cursor.
@discussion Invalidates and releases any <code>NSTimer</code> instance associated with this
cursor.
@discussion Invalidates and releases any <code>NSTimer</code> instance
associated with this cursor.
*/
/*! @method advanceAnimatedCursor:
@abstract Method called by animation timer to perform animation.
@discussion Called by an animated cursor's associated timer to advance the animation to the next
frame. Determines which frame should occur next and sets the cursor to that frame.
@discussion Called by an animated cursor's associated timer to advance the
animation to the next frame. Determines which frame should occur next and
sets the cursor to that frame.
@param aTimer the timer causing the animation
*/
- (void)advanceAnimatedCursor:(NSTimer*)aTimer;
/*! @method setFrame:
@abstract Sets the current cursor, using an index to determine which frame in the animation to
display.
@discussion Sets the current cursor. The frame index determines which frame is shown if the
cursor is animated. Frames and numbered from <code>0</code> to <code>-[nsMacCursor numFrames] -
1</code>. A static cursor has a single frame, numbered 0.
@param aFrameIndex the index indicating which frame from the animation to display
@abstract Sets the current cursor, using an index to determine which frame
in the animation to display.
@discussion Sets the current cursor. The frame index determines which frame
is shown if the cursor is animated. Frames and numbered from <code>0</code>
to <code>-[nsMacCursor numFrames] - 1</code>. A static cursor has a single
frame, numbered 0.
@param aFrameIndex the index indicating which frame from the animation
to display
*/
- (void)setFrame:(int)aFrameIndex;
@end
/*! @class nsCocoaCursor
@abstract Implementation of <code>nsMacCursor</code> that uses Cocoa <code>NSCursor</code>
instances.
@discussion Displays a static or animated cursor, using Cocoa <code>NSCursor</code> instances.
These can be either built-in <code>NSCursor</code> instances, or custom <code>NSCursor</code>s
created from images. When more than one <code>NSCursor</code> is provided, the cursor will use
these as animation frames.
@abstract Implementation of <code>nsMacCursor</code> that uses Cocoa
<code>NSCursor</code> instances.
@discussion Displays a static or animated cursor, using Cocoa
<code>NSCursor</code> instances. These can be either built-in
<code>NSCursor</code> instances, or custom <code>NSCursor</code>s created
from images. When more than one <code>NSCursor</code> is provided, the cursor
will use these as animation frames.
*/
@interface nsCocoaCursor : nsMacCursor {
@private
@ -85,13 +91,16 @@
}
/*! @method initWithFrames:
@abstract Create an animated cursor by specifying the frames to use for the animation.
@discussion Creates a cursor that will animate by cycling through the given frames. Each element
of the array must be an instance of <code>NSCursor</code>
@param aCursorFrames an array of <code>NSCursor</code>, representing the frames of an
animated cursor, in the order they should be played.
@abstract Create an animated cursor by specifying the frames to use for
the animation.
@discussion Creates a cursor that will animate by cycling through the given
frames. Each element of the array must be an instance of
<code>NSCursor</code>
@param aCursorFrames an array of <code>NSCursor</code>, representing
the frames of an animated cursor, in the order they should be played.
@param aType the corresponding <code>nsCursor</code> constant
@result an instance of <code>nsCocoaCursor</code> that will animate the given cursor frames
@result an instance of <code>nsCocoaCursor</code> that will animate the
given cursor frames
*/
- (id)initWithFrames:(NSArray*)aCursorFrames type:(nsCursor)aType;
@ -106,18 +115,22 @@
- (id)initWithCursor:(NSCursor*)aCursor type:(nsCursor)aType;
/*! @method initWithImageNamed:hotSpot:
@abstract Create a cursor by specifying the name of an image resource to use for the cursor
and a hotspot.
@discussion Creates a cursor by loading the named image using the <code>+[NSImage
imageNamed:]</code> method. <p>The image must be compatible with any restrictions laid down by
<code>NSCursor</code>. These vary by operating system version.</p> <p>The hotspot precisely
determines the point where the user clicks when using the cursor.</p>
@abstract Create a cursor by specifying the name of an image resource to
use for the cursor and a hotspot.
@discussion Creates a cursor by loading the named image using the
<code>+[NSImage imageNamed:]</code> method. <p>The image must be compatible
with any restrictions laid down by <code>NSCursor</code>. These vary by
operating system version.</p> <p>The hotspot precisely determines the point
where the user clicks when using the cursor.</p>
@param aCursor the name of the image to use for the cursor
@param aPoint the point within the cursor to use as the hotspot
@param aType the corresponding <code>nsCursor</code> constant
@result an instance of <code>nsCocoaCursor</code> that uses the given image and hotspot
@result an instance of <code>nsCocoaCursor</code> that uses the given
image and hotspot
*/
- (id)initWithImageNamed:(NSString*)aCursorImage hotSpot:(NSPoint)aPoint type:(nsCursor)aType;
- (id)initWithImageNamed:(NSString*)aCursorImage
hotSpot:(NSPoint)aPoint
type:(nsCursor)aType;
@end
@ -126,7 +139,8 @@
+ (nsMacCursor*)cursorWithCursor:(NSCursor*)aCursor type:(nsCursor)aType {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return [[[nsCocoaCursor alloc] initWithCursor:aCursor type:aType] autorelease];
return [[[nsCocoaCursor alloc] initWithCursor:aCursor
type:aType] autorelease];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
@ -136,7 +150,8 @@
type:(nsCursor)aType {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return [[[nsCocoaCursor alloc] initWithImageNamed:aCursorImage hotSpot:aPoint
return [[[nsCocoaCursor alloc] initWithImageNamed:aCursorImage
hotSpot:aPoint
type:aType] autorelease];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
@ -145,12 +160,14 @@
+ (nsMacCursor*)cursorWithFrames:(NSArray*)aCursorFrames type:(nsCursor)aType {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return [[[nsCocoaCursor alloc] initWithFrames:aCursorFrames type:aType] autorelease];
return [[[nsCocoaCursor alloc] initWithFrames:aCursorFrames
type:aType] autorelease];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
+ (NSCursor*)cocoaCursorWithImageNamed:(NSString*)imageName hotSpot:(NSPoint)aPoint {
+ (NSCursor*)cocoaCursorWithImageNamed:(NSString*)imageName
hotSpot:(NSPoint)aPoint {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsCOMPtr<nsIFile> resDir;
@ -174,22 +191,26 @@
pathToImage = [pathToImage stringByAppendingPathExtension:@"png"];
pathToHiDpiImage = [pathToHiDpiImage stringByAppendingPathExtension:@"png"];
cursorImage = [[[NSImage alloc] initWithContentsOfFile:pathToImage] autorelease];
cursorImage =
[[[NSImage alloc] initWithContentsOfFile:pathToImage] autorelease];
if (!cursorImage) goto INIT_FAILURE;
// Note 1: There are a few different ways to get a hidpi image via
// initWithContentsOfFile. We let the OS handle this here: when the
// file basename ends in "@2x", it will be displayed at native resolution
// instead of being pixel-doubled. See bug 784909 comment 7 for alternates ways.
// instead of being pixel-doubled. See bug 784909 comment 7 for alternates
// ways.
//
// Note 2: The OS is picky, and will ignore the hidpi representation
// unless it is exactly twice the size of the lowdpi image.
hiDpiCursorImage = [[[NSImage alloc] initWithContentsOfFile:pathToHiDpiImage] autorelease];
hiDpiCursorImage =
[[[NSImage alloc] initWithContentsOfFile:pathToHiDpiImage] autorelease];
if (hiDpiCursorImage) {
NSImageRep* imageRep = [[hiDpiCursorImage representations] objectAtIndex:0];
[cursorImage addRepresentation:imageRep];
}
return [[[NSCursor alloc] initWithImage:cursorImage hotSpot:aPoint] autorelease];
return [[[NSCursor alloc] initWithImage:cursorImage
hotSpot:aPoint] autorelease];
INIT_FAILURE:
NS_WARNING("Problem getting path to cursor image file!");
@ -236,11 +257,12 @@ INIT_FAILURE:
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!mTimer) {
mTimer = [[NSTimer scheduledTimerWithTimeInterval:0.25
target:self
selector:@selector(advanceAnimatedCursor:)
userInfo:nil
repeats:YES] retain];
mTimer = [[NSTimer
scheduledTimerWithTimeInterval:0.25
target:self
selector:@selector(advanceAnimatedCursor:)
userInfo:nil
repeats:YES] retain];
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
@ -316,11 +338,15 @@ INIT_FAILURE:
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
- (id)initWithImageNamed:(NSString*)aCursorImage hotSpot:(NSPoint)aPoint type:(nsCursor)aType {
- (id)initWithImageNamed:(NSString*)aCursorImage
hotSpot:(NSPoint)aPoint
type:(nsCursor)aType {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return [self initWithCursor:[nsMacCursor cocoaCursorWithImageNamed:aCursorImage hotSpot:aPoint]
type:aType];
return
[self initWithCursor:[nsMacCursor cocoaCursorWithImageNamed:aCursorImage
hotSpot:aPoint]
type:aType];
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}

Просмотреть файл

@ -32,7 +32,8 @@ NS_IMPL_ISUPPORTS(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress)
@synthesize fractionValue = mFractionValue;
- (void)drawRect:(NSRect)aRect {
// Erase the background behind this view, i.e. cut a rectangle hole in the icon.
// Erase the background behind this view, i.e. cut a rectangle hole in the
// icon.
[[NSColor clearColor] set];
NSRectFill(self.bounds);
@ -103,7 +104,8 @@ NS_IMETHODIMP
nsMacDockSupport::ActivateApplication(bool aIgnoreOtherApplications) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
[[NSApplication sharedApplication] activateIgnoringOtherApps:aIgnoreOtherApplications];
[[NSApplication sharedApplication]
activateIgnoringOtherApps:aIgnoreOtherApplications];
return NS_OK;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
@ -118,9 +120,11 @@ nsMacDockSupport::SetBadgeText(const nsAString& aBadgeText) {
if (aBadgeText.IsEmpty())
[tile setBadgeLabel:nil];
else
[tile setBadgeLabel:[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(mBadgeText.get())
length:mBadgeText.Length()]];
[tile
setBadgeLabel:[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(
mBadgeText.get())
length:mBadgeText.Length()]];
return NS_OK;
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
@ -133,8 +137,8 @@ nsMacDockSupport::GetBadgeText(nsAString& aBadgeText) {
}
NS_IMETHODIMP
nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState, uint64_t aCurrentValue,
uint64_t aMaxValue) {
nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState,
uint64_t aCurrentValue, uint64_t aMaxValue) {
NS_ENSURE_ARG_RANGE(aState, 0, STATE_PAUSED);
if (aState == STATE_NO_PROGRESS || aState == STATE_INDETERMINATE) {
NS_ENSURE_TRUE(aCurrentValue == 0, NS_ERROR_INVALID_ARG);
@ -162,22 +166,26 @@ nsresult nsMacDockSupport::UpdateDockTile() {
// Create the following NSView hierarchy:
// * mDockTileWrapperView (NSView)
// * imageView (NSImageView) <- has the application icon
// * mProgressDockOverlayView (MOZProgressDockOverlayView) <- draws the progress bar
// * mProgressDockOverlayView (MOZProgressDockOverlayView) <- draws the
// progress bar
mDockTileWrapperView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
mDockTileWrapperView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
mDockTileWrapperView =
[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)];
mDockTileWrapperView.autoresizingMask =
NSViewWidthSizable | NSViewHeightSizable;
NSImageView* imageView = [[NSImageView alloc] initWithFrame:[mDockTileWrapperView bounds]];
NSImageView* imageView =
[[NSImageView alloc] initWithFrame:[mDockTileWrapperView bounds]];
imageView.image = [NSImage imageNamed:@"NSApplicationIcon"];
imageView.imageScaling = NSImageScaleAxesIndependently;
imageView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[mDockTileWrapperView addSubview:imageView];
mProgressDockOverlayView =
[[MOZProgressDockOverlayView alloc] initWithFrame:NSMakeRect(1, 3, 30, 4)];
mProgressDockOverlayView.autoresizingMask = NSViewMinXMargin | NSViewWidthSizable |
NSViewMaxXMargin | NSViewMinYMargin |
NSViewHeightSizable | NSViewMaxYMargin;
mProgressDockOverlayView = [[MOZProgressDockOverlayView alloc]
initWithFrame:NSMakeRect(1, 3, 30, 4)];
mProgressDockOverlayView.autoresizingMask =
NSViewMinXMargin | NSViewWidthSizable | NSViewMaxXMargin |
NSViewMinYMargin | NSViewHeightSizable | NSViewMaxYMargin;
[mDockTileWrapperView addSubview:mProgressDockOverlayView];
}
if (NSApp.dockTile.contentView != mDockTileWrapperView) {
@ -205,21 +213,23 @@ nsresult nsMacDockSupport::UpdateDockTile() {
extern "C" {
// Private CFURL API used by the Dock.
CFPropertyListRef _CFURLCopyPropertyListRepresentation(CFURLRef url);
CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc,
CFPropertyListRef pListRepresentation);
CFURLRef _CFURLCreateFromPropertyListRepresentation(
CFAllocatorRef alloc, CFPropertyListRef pListRepresentation);
} // extern "C"
namespace {
const NSArray* const browserAppNames =
[NSArray arrayWithObjects:@"Firefox.app", @"Firefox Beta.app", @"Firefox Nightly.app",
@"Safari.app", @"WebKit.app", @"Google Chrome.app",
@"Google Chrome Canary.app", @"Chromium.app", @"Opera.app", nil];
const NSArray* const browserAppNames = [NSArray
arrayWithObjects:@"Firefox.app", @"Firefox Beta.app",
@"Firefox Nightly.app", @"Safari.app", @"WebKit.app",
@"Google Chrome.app", @"Google Chrome Canary.app",
@"Chromium.app", @"Opera.app", nil];
constexpr NSString* const kDockDomainName = @"com.apple.dock";
// See https://developer.apple.com/documentation/devicemanagement/dock
constexpr NSString* const kDockPersistentAppsKey = @"persistent-apps";
// See https://developer.apple.com/documentation/devicemanagement/dock/staticitem
// See
// https://developer.apple.com/documentation/devicemanagement/dock/staticitem
constexpr NSString* const kDockTileDataKey = @"tile-data";
constexpr NSString* const kDockFileDataKey = @"file-data";
@ -247,7 +257,8 @@ NSString* GetPathForApp(NSDictionary* aPersistantApp) {
// Some special tiles may not have DockFileData but we can ignore those.
return nil;
}
NSURL* url = CFBridgingRelease(_CFURLCreateFromPropertyListRepresentation(NULL, fileData));
NSURL* url = CFBridgingRelease(
_CFURLCreateFromPropertyListRepresentation(NULL, fileData));
if (!url) {
return nil;
}
@ -257,7 +268,8 @@ NSString* GetPathForApp(NSDictionary* aPersistantApp) {
// The only reliable way to get our changes to take effect seems to be to use
// `kill`.
void RefreshDock(NSDictionary* aDockPlist) {
[[NSUserDefaults standardUserDefaults] setPersistentDomain:aDockPlist forName:kDockDomainName];
[[NSUserDefaults standardUserDefaults] setPersistentDomain:aDockPlist
forName:kDockDomainName];
NSRunningApplication* dockApp = [[NSRunningApplication
runningApplicationsWithBundleIdentifier:@"com.apple.dock"] firstObject];
if (!dockApp) {
@ -276,8 +288,8 @@ nsresult nsMacDockSupport::GetIsAppInDock(bool* aIsInDock) {
*aIsInDock = false;
NSDictionary* dockPlist =
[[NSUserDefaults standardUserDefaults] persistentDomainForName:kDockDomainName];
NSDictionary* dockPlist = [[NSUserDefaults standardUserDefaults]
persistentDomainForName:kDockDomainName];
if (!dockPlist) {
return NS_ERROR_FAILURE;
}
@ -302,22 +314,22 @@ nsresult nsMacDockSupport::GetIsAppInDock(bool* aIsInDock) {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
nsresult nsMacDockSupport::EnsureAppIsPinnedToDock(const nsAString& aAppPath,
const nsAString& aAppToReplacePath,
bool* aIsInDock) {
nsresult nsMacDockSupport::EnsureAppIsPinnedToDock(
const nsAString& aAppPath, const nsAString& aAppToReplacePath,
bool* aIsInDock) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_ASSERT(aAppPath != aAppToReplacePath || !aAppPath.IsEmpty());
*aIsInDock = false;
NSString* appPath =
!aAppPath.IsEmpty() ? nsCocoaUtils::ToNSString(aAppPath) : [[NSBundle mainBundle] bundlePath];
NSString* appPath = !aAppPath.IsEmpty() ? nsCocoaUtils::ToNSString(aAppPath)
: [[NSBundle mainBundle] bundlePath];
NSString* appToReplacePath = nsCocoaUtils::ToNSString(aAppToReplacePath);
NSMutableDictionary* dockPlist =
[NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults]
persistentDomainForName:kDockDomainName]];
NSMutableDictionary* dockPlist = [NSMutableDictionary
dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults]
persistentDomainForName:kDockDomainName]];
if (!dockPlist) {
return NS_ERROR_FAILURE;
}
@ -335,11 +347,13 @@ nsresult nsMacDockSupport::EnsureAppIsPinnedToDock(const nsAString& aAppPath,
NSUInteger toReplaceAppIndex = NSNotFound;
NSUInteger lastBrowserAppIndex = NSNotFound;
for (NSUInteger index = 0; index < [persistentApps count]; ++index) {
NSString* persistentAppPath = GetPathForApp([persistentApps objectAtIndex:index]);
NSString* persistentAppPath =
GetPathForApp([persistentApps objectAtIndex:index]);
if ([persistentAppPath isEqualToString:appPath]) {
preexistingAppIndex = index;
} else if (appToReplacePath && [persistentAppPath isEqualToString:appToReplacePath]) {
} else if (appToReplacePath &&
[persistentAppPath isEqualToString:appToReplacePath]) {
toReplaceAppIndex = index;
} else {
NSString* appName = [appPath lastPathComponent];
@ -381,14 +395,16 @@ nsresult nsMacDockSupport::EnsureAppIsPinnedToDock(const nsAString& aAppPath,
NSDictionary* newDockTile = nullptr;
{
NSURL* appUrl = [NSURL fileURLWithPath:appPath isDirectory:YES];
NSDictionary* dict =
CFBridgingRelease(_CFURLCopyPropertyListRepresentation((__bridge CFURLRef)appUrl));
NSDictionary* dict = CFBridgingRelease(
_CFURLCopyPropertyListRepresentation((__bridge CFURLRef)appUrl));
if (!dict) {
return NS_ERROR_FAILURE;
}
NSDictionary* dockTileData = [NSDictionary dictionaryWithObject:dict forKey:kDockFileDataKey];
NSDictionary* dockTileData =
[NSDictionary dictionaryWithObject:dict forKey:kDockFileDataKey];
if (dockTileData) {
newDockTile = [NSDictionary dictionaryWithObject:dockTileData forKey:kDockTileDataKey];
newDockTile = [NSDictionary dictionaryWithObject:dockTileData
forKey:kDockTileDataKey];
}
if (!newDockTile) {
return NS_ERROR_FAILURE;
@ -397,7 +413,8 @@ nsresult nsMacDockSupport::EnsureAppIsPinnedToDock(const nsAString& aAppPath,
// Update the Dock:
if (toReplaceAppIndex != NSNotFound) {
[persistentApps replaceObjectAtIndex:toReplaceAppIndex withObject:newDockTile];
[persistentApps replaceObjectAtIndex:toReplaceAppIndex
withObject:newDockTile];
} else {
NSUInteger index;
if (sameNameAppIndex != NSNotFound) {

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset:
* 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -24,16 +25,19 @@ nsMacFinderProgress::~nsMacFinderProgress() {
}
NS_IMETHODIMP
nsMacFinderProgress::Init(const nsAString& path,
nsIMacFinderProgressCanceledCallback* cancellationCallback) {
nsMacFinderProgress::Init(
const nsAString& path,
nsIMacFinderProgressCanceledCallback* cancellationCallback) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSURL* pathUrl = [NSURL
fileURLWithPath:[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(path.BeginReading())
stringWithCharacters:reinterpret_cast<const unichar*>(
path.BeginReading())
length:path.Length()]];
NSDictionary* userInfo = @{
@"NSProgressFileOperationKindKey" : @"NSProgressFileOperationKindDownloading",
@"NSProgressFileOperationKindKey" :
@"NSProgressFileOperationKindDownloading",
@"NSProgressFileURLKey" : pathUrl
};
@ -41,13 +45,14 @@ nsMacFinderProgress::Init(const nsAString& path,
mProgress.kind = NSProgressKindFile;
mProgress.cancellable = YES;
nsMainThreadPtrHandle<nsIMacFinderProgressCanceledCallback> cancellationCallbackHandle(
new nsMainThreadPtrHolder<nsIMacFinderProgressCanceledCallback>(
"MacFinderProgress::CancellationCallback", cancellationCallback));
nsMainThreadPtrHandle<nsIMacFinderProgressCanceledCallback>
cancellationCallbackHandle(
new nsMainThreadPtrHolder<nsIMacFinderProgressCanceledCallback>(
"MacFinderProgress::CancellationCallback", cancellationCallback));
mProgress.cancellationHandler = ^{
NS_DispatchToMainThread(
NS_NewRunnableFunction("MacFinderProgress::Canceled", [cancellationCallbackHandle] {
NS_DispatchToMainThread(NS_NewRunnableFunction(
"MacFinderProgress::Canceled", [cancellationCallbackHandle] {
MOZ_ASSERT(NS_IsMainThread());
cancellationCallbackHandle->Canceled();
}));
@ -61,7 +66,8 @@ nsMacFinderProgress::Init(const nsAString& path,
}
NS_IMETHODIMP
nsMacFinderProgress::UpdateProgress(uint64_t currentProgress, uint64_t totalProgress) {
nsMacFinderProgress::UpdateProgress(uint64_t currentProgress,
uint64_t totalProgress) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (mProgress) {
mProgress.totalUnitCount = totalProgress;

Просмотреть файл

@ -15,11 +15,13 @@
NS_IMPL_ISUPPORTS(nsMacSharingService, nsIMacSharingService)
NSString* const remindersServiceName = @"com.apple.reminders.RemindersShareExtension";
NSString* const remindersServiceName =
@"com.apple.reminders.RemindersShareExtension";
// These are some undocumented constants also used by Safari
// to let us open the preferences window
NSString* const extensionPrefPanePath = @"/System/Library/PreferencePanes/Extensions.prefPane";
NSString* const extensionPrefPanePath =
@"/System/Library/PreferencePanes/Extensions.prefPane";
const UInt32 openSharingSubpaneDescriptorType = 'ptru';
NSString* const openSharingSubpaneActionKey = @"action";
NSString* const openSharingSubpaneActionValue = @"revealExtensionPoint";
@ -31,10 +33,11 @@ NSString* const openSharingSubpaneProtocolValue = @"com.apple.share-services";
- (id)name;
@end
// Filter providers that we do not want to expose to the user, because they are duplicates or do not
// work correctly within the context
// Filter providers that we do not want to expose to the user, because they are
// duplicates or do not work correctly within the context
static bool ShouldIgnoreProvider(NSString* aProviderName) {
return [aProviderName isEqualToString:@"com.apple.share.System.add-to-safari-reading-list"];
return [aProviderName
isEqualToString:@"com.apple.share.System.add-to-safari-reading-list"];
}
// Clean up the activity once the share is complete
@ -61,7 +64,8 @@ static bool ShouldIgnoreProvider(NSString* aProviderName) {
mShareActivity = nil;
}
- (void)sharingService:(NSSharingService*)sharingService didShareItems:(NSArray*)items {
- (void)sharingService:(NSSharingService*)sharingService
didShareItems:(NSArray*)items {
[self cleanup];
}
@ -80,16 +84,18 @@ static bool ShouldIgnoreProvider(NSString* aProviderName) {
static NSString* NSImageToBase64(const NSImage* aImage) {
CGImageRef cgRef = [aImage CGImageForProposedRect:nil context:nil hints:nil];
NSBitmapImageRep* bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
NSBitmapImageRep* bitmapRep =
[[NSBitmapImageRep alloc] initWithCGImage:cgRef];
[bitmapRep setSize:[aImage size]];
NSData* imageData = [bitmapRep representationUsingType:NSPNGFileType properties:@{}];
NSData* imageData = [bitmapRep representationUsingType:NSPNGFileType
properties:@{}];
NSString* base64Encoded = [imageData base64EncodedStringWithOptions:0];
[bitmapRep release];
return [NSString stringWithFormat:@"data:image/png;base64,%@", base64Encoded];
}
static void SetStrAttribute(JSContext* aCx, JS::Rooted<JSObject*>& aObj, const char* aKey,
NSString* aVal) {
static void SetStrAttribute(JSContext* aCx, JS::Rooted<JSObject*>& aObj,
const char* aKey, NSString* aVal) {
nsAutoString strVal;
mozilla::CopyCocoaStringToXPCOMString(aVal, strVal);
JS::Rooted<JSString*> title(aCx, JS_NewUCStringCopyZ(aCx, strVal.get()));
@ -97,8 +103,9 @@ static void SetStrAttribute(JSContext* aCx, JS::Rooted<JSObject*>& aObj, const c
JS_SetProperty(aCx, aObj, aKey, attVal);
}
nsresult nsMacSharingService::GetSharingProviders(const nsAString& aPageUrl, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
nsresult nsMacSharingService::GetSharingProviders(
const nsAString& aPageUrl, JSContext* aCx,
JS::MutableHandle<JS::Value> aResult) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSURL* url = nsCocoaUtils::ToNSURL(aPageUrl);
@ -135,18 +142,20 @@ NS_IMETHODIMP
nsMacSharingService::OpenSharingPreferences() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSURL* prefPaneURL = [NSURL fileURLWithPath:extensionPrefPanePath isDirectory:YES];
NSURL* prefPaneURL = [NSURL fileURLWithPath:extensionPrefPanePath
isDirectory:YES];
NSDictionary* args = @{
openSharingSubpaneActionKey : openSharingSubpaneActionValue,
openSharingSubpaneProtocolKey : openSharingSubpaneProtocolValue
};
NSData* data = [NSPropertyListSerialization dataWithPropertyList:args
format:NSPropertyListXMLFormat_v1_0
options:0
error:nil];
NSAppleEventDescriptor* descriptor =
[[NSAppleEventDescriptor alloc] initWithDescriptorType:openSharingSubpaneDescriptorType
data:data];
NSData* data = [NSPropertyListSerialization
dataWithPropertyList:args
format:NSPropertyListXMLFormat_v1_0
options:0
error:nil];
NSAppleEventDescriptor* descriptor = [[NSAppleEventDescriptor alloc]
initWithDescriptorType:openSharingSubpaneDescriptorType
data:data];
[[NSWorkspace sharedWorkspace] openURLs:@[ prefPaneURL ]
withAppBundleIdentifier:nil
@ -161,19 +170,21 @@ nsMacSharingService::OpenSharingPreferences() {
}
NS_IMETHODIMP
nsMacSharingService::ShareUrl(const nsAString& aServiceName, const nsAString& aPageUrl,
nsMacSharingService::ShareUrl(const nsAString& aServiceName,
const nsAString& aPageUrl,
const nsAString& aPageTitle) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
NSString* serviceName = nsCocoaUtils::ToNSString(aServiceName);
NSURL* pageUrl = nsCocoaUtils::ToNSURL(aPageUrl);
NSString* pageTitle = nsCocoaUtils::ToNSString(aPageTitle);
NSSharingService* service = [NSSharingService sharingServiceNamed:serviceName];
NSSharingService* service =
[NSSharingService sharingServiceNamed:serviceName];
// Reminders fetch its data from an activity, not the share data
if ([[service name] isEqual:remindersServiceName]) {
NSUserActivity* shareActivity =
[[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
NSUserActivity* shareActivity = [[NSUserActivity alloc]
initWithActivityType:NSUserActivityTypeBrowsingWeb];
if ([pageUrl.scheme hasPrefix:@"http"]) {
[shareActivity setWebpageURL:pageUrl];

Просмотреть файл

@ -13,7 +13,8 @@
NS_IMPL_ISUPPORTS(nsMacUserActivityUpdater, nsIMacUserActivityUpdater)
NS_IMETHODIMP
nsMacUserActivityUpdater::UpdateLocation(const nsAString& aPageUrl, const nsAString& aPageTitle,
nsMacUserActivityUpdater::UpdateLocation(const nsAString& aPageUrl,
const nsAString& aPageTitle,
nsIBaseWindow* aWindow) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (gfxPlatform::IsHeadless()) {
@ -27,8 +28,8 @@ nsMacUserActivityUpdater::UpdateLocation(const nsAString& aPageUrl, const nsAStr
}
NSURL* pageUrl = nsCocoaUtils::ToNSURL(aPageUrl);
if (!pageUrl ||
(![pageUrl.scheme isEqualToString:@"https"] && ![pageUrl.scheme isEqualToString:@"http"])) {
if (!pageUrl || (![pageUrl.scheme isEqualToString:@"https"] &&
![pageUrl.scheme isEqualToString:@"http"])) {
[cocoaWin.userActivity invalidate];
return NS_OK;
}
@ -38,8 +39,8 @@ nsMacUserActivityUpdater::UpdateLocation(const nsAString& aPageUrl, const nsAStr
pageTitle = pageUrl.absoluteString;
}
NSUserActivity* userActivity =
[[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
NSUserActivity* userActivity = [[NSUserActivity alloc]
initWithActivityType:NSUserActivityTypeBrowsingWeb];
userActivity.webpageURL = pageUrl;
userActivity.title = pageTitle;
cocoaWin.userActivity = userActivity;

Просмотреть файл

@ -13,25 +13,28 @@
#include "nsObjCExceptions.h"
// Find the path to the app with the given bundleIdentifier, if any.
// Note that the OS will return the path to the newest binary, if there is more than one.
// The determination of 'newest' is complex and beyond the scope of this comment.
// Note that the OS will return the path to the newest binary, if there is more
// than one. The determination of 'newest' is complex and beyond the scope of
// this comment.
NS_IMPL_ISUPPORTS(nsMacWebAppUtils, nsIMacWebAppUtils)
NS_IMETHODIMP nsMacWebAppUtils::PathForAppWithIdentifier(const nsAString& bundleIdentifier,
nsAString& outPath) {
NS_IMETHODIMP nsMacWebAppUtils::PathForAppWithIdentifier(
const nsAString& bundleIdentifier, nsAString& outPath) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
outPath.Truncate();
nsAutoreleasePool localPool;
// note that the result of this expression might be nil, meaning no matching app was found.
// note that the result of this expression might be nil, meaning no matching
// app was found.
NSString* temp = [[NSWorkspace sharedWorkspace]
absolutePathForAppBundleWithIdentifier:
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
((nsString)bundleIdentifier).get())
length:((nsString)bundleIdentifier).Length()]];
[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(
((nsString)bundleIdentifier).get())
length:((nsString)bundleIdentifier).Length()]];
if (temp) {
// Copy out the resultant absolute path into outPath if non-nil.
@ -43,18 +46,20 @@ NS_IMETHODIMP nsMacWebAppUtils::PathForAppWithIdentifier(const nsAString& bundle
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
NS_IMETHODIMP nsMacWebAppUtils::LaunchAppWithIdentifier(const nsAString& bundleIdentifier) {
NS_IMETHODIMP nsMacWebAppUtils::LaunchAppWithIdentifier(
const nsAString& bundleIdentifier) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
nsAutoreleasePool localPool;
// Note this might return false, meaning the app wasnt launched for some reason.
// Note this might return false, meaning the app wasnt launched for some
// reason.
BOOL success = [[NSWorkspace sharedWorkspace]
launchAppWithBundleIdentifier:[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(
((nsString)bundleIdentifier)
.get())
length:((nsString)bundleIdentifier).Length()]
launchAppWithBundleIdentifier:
[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(
((nsString)bundleIdentifier).get())
length:((nsString)bundleIdentifier).Length()]
options:(NSWorkspaceLaunchOptions)0
additionalEventParamDescriptor:nil
launchIdentifier:NULL];
@ -64,7 +69,8 @@ NS_IMETHODIMP nsMacWebAppUtils::LaunchAppWithIdentifier(const nsAString& bundleI
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
NS_IMETHODIMP nsMacWebAppUtils::TrashApp(const nsAString& path, nsITrashAppCallback* aCallback) {
NS_IMETHODIMP nsMacWebAppUtils::TrashApp(const nsAString& path,
nsITrashAppCallback* aCallback) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
if (NS_WARN_IF(!aCallback)) {
@ -74,11 +80,13 @@ NS_IMETHODIMP nsMacWebAppUtils::TrashApp(const nsAString& path, nsITrashAppCallb
nsCOMPtr<nsITrashAppCallback> callback = aCallback;
NSString* tempString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(((nsString)path).get())
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
((nsString)path).get())
length:path.Length()];
[[NSWorkspace sharedWorkspace]
recycleURLs:[NSArray arrayWithObject:[NSURL fileURLWithPath:tempString]]
recycleURLs:[NSArray
arrayWithObject:[NSURL fileURLWithPath:tempString]]
completionHandler:^(NSDictionary* newURLs, NSError* error) {
nsresult rv = (error == nil) ? NS_OK : NS_ERROR_FAILURE;
callback->TrashAppFinished(rv);

Просмотреть файл

@ -41,10 +41,11 @@ BOOL gSomeMenuBarPainted = NO;
// defined in nsCocoaWindow.mm.
extern BOOL sTouchBarIsInitialized;
// We keep references to the first quit and pref item content nodes we find, which
// will be from the hidden window. We use these when the document for the current
// window does not have a quit or pref item. We don't need strong refs here because
// these items are always strong ref'd by their owning menu bar (instance variable).
// We keep references to the first quit and pref item content nodes we find,
// which will be from the hidden window. We use these when the document for the
// current window does not have a quit or pref item. We don't need strong refs
// here because these items are always strong ref'd by their owning menu bar
// (instance variable).
static nsIContent* sAboutItemContent = nullptr;
static nsIContent* sPrefItemContent = nullptr;
static nsIContent* sAccountItemContent = nullptr;
@ -140,8 +141,9 @@ void nsMenuBarX::ConstructNativeMenus() {
for (nsIContent* menuContent = mContent->GetFirstChild(); menuContent;
menuContent = menuContent->GetNextSibling()) {
if (menuContent->IsXULElement(nsGkAtoms::menu)) {
InsertMenuAtIndex(MakeRefPtr<nsMenuX>(this, mMenuGroupOwner, menuContent->AsElement()),
GetMenuCount());
InsertMenuAtIndex(
MakeRefPtr<nsMenuX>(this, mMenuGroupOwner, menuContent->AsElement()),
GetMenuCount());
}
}
}
@ -156,7 +158,8 @@ void nsMenuBarX::ConstructFallbackNativeMenus() {
nsCOMPtr<nsIStringBundle> stringBundle;
nsCOMPtr<nsIStringBundleService> bundleSvc = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
nsCOMPtr<nsIStringBundleService> bundleSvc =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
bundleSvc->CreateBundle("chrome://global/locale/fallbackMenubar.properties",
getter_AddRefs(stringBundle));
@ -173,8 +176,10 @@ void nsMenuBarX::ConstructFallbackNativeMenus() {
stringBundle->GetStringFromName(labelProp, labelUTF16);
stringBundle->GetStringFromName(keyProp, keyUTF16);
NSString* labelStr = [NSString stringWithUTF8String:NS_ConvertUTF16toUTF8(labelUTF16).get()];
NSString* keyStr = [NSString stringWithUTF8String:NS_ConvertUTF16toUTF8(keyUTF16).get()];
NSString* labelStr =
[NSString stringWithUTF8String:NS_ConvertUTF16toUTF8(labelUTF16).get()];
NSString* keyStr =
[NSString stringWithUTF8String:NS_ConvertUTF16toUTF8(keyUTF16).get()];
if (!nsMenuBarX::sNativeEventTarget) {
nsMenuBarX::sNativeEventTarget = [[NativeMenuItemTarget alloc] init];
@ -182,12 +187,14 @@ void nsMenuBarX::ConstructFallbackNativeMenus() {
sApplicationMenu = [[[[NSApp mainMenu] itemAtIndex:0] submenu] retain];
if (!mApplicationMenuDelegate) {
mApplicationMenuDelegate = [[ApplicationMenuDelegate alloc] initWithApplicationMenu:this];
mApplicationMenuDelegate =
[[ApplicationMenuDelegate alloc] initWithApplicationMenu:this];
}
sApplicationMenu.delegate = mApplicationMenuDelegate;
NSMenuItem* quitMenuItem = [[[NSMenuItem alloc] initWithTitle:labelStr
action:@selector(menuItemHit:)
keyEquivalent:keyStr] autorelease];
NSMenuItem* quitMenuItem =
[[[NSMenuItem alloc] initWithTitle:labelStr
action:@selector(menuItemHit:)
keyEquivalent:keyStr] autorelease];
quitMenuItem.target = nsMenuBarX::sNativeEventTarget;
quitMenuItem.tag = eCommand_ID_Quit;
[sApplicationMenu addItem:quitMenuItem];
@ -201,7 +208,8 @@ uint32_t nsMenuBarX::GetMenuCount() { return mMenuArray.Length(); }
bool nsMenuBarX::MenuContainsAppMenu() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
return (mNativeMenu.numberOfItems > 0 && [mNativeMenu itemAtIndex:0].submenu == sApplicationMenu);
return (mNativeMenu.numberOfItems > 0 &&
[mNativeMenu itemAtIndex:0].submenu == sApplicationMenu);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
@ -220,8 +228,9 @@ void nsMenuBarX::InsertMenuAtIndex(RefPtr<nsMenuX>&& aMenu, uint32_t aIndex) {
// Hook the new Application menu up to the menu bar.
NSMenu* mainMenu = NSApp.mainMenu;
NS_ASSERTION(mainMenu.numberOfItems > 0,
"Main menu does not have any items, something is terribly wrong!");
NS_ASSERTION(
mainMenu.numberOfItems > 0,
"Main menu does not have any items, something is terribly wrong!");
[mainMenu itemAtIndex:0].submenu = sApplicationMenu;
}
@ -230,7 +239,8 @@ void nsMenuBarX::InsertMenuAtIndex(RefPtr<nsMenuX>&& aMenu, uint32_t aIndex) {
// hook up submenus
RefPtr<nsIContent> menuContent = aMenu->Content();
if (menuContent->GetChildCount() > 0 && !nsMenuUtilsX::NodeIsHiddenOrCollapsed(menuContent)) {
if (menuContent->GetChildCount() > 0 &&
!nsMenuUtilsX::NodeIsHiddenOrCollapsed(menuContent)) {
MenuChildChangedVisibility(MenuChild(aMenu), true);
}
@ -263,11 +273,14 @@ void nsMenuBarX::RemoveMenuAtIndex(uint32_t aIndex) {
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsMenuBarX::ObserveAttributeChanged(mozilla::dom::Document* aDocument, nsIContent* aContent,
void nsMenuBarX::ObserveAttributeChanged(mozilla::dom::Document* aDocument,
nsIContent* aContent,
nsAtom* aAttribute) {}
void nsMenuBarX::ObserveContentRemoved(mozilla::dom::Document* aDocument, nsIContent* aContainer,
nsIContent* aChild, nsIContent* aPreviousSibling) {
void nsMenuBarX::ObserveContentRemoved(mozilla::dom::Document* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
nsIContent* aPreviousSibling) {
nsINode* parent = NODE_FROM(aContainer, aDocument);
MOZ_ASSERT(parent);
const Maybe<uint32_t> index = parent->ComputeIndexOf(aPreviousSibling);
@ -275,7 +288,8 @@ void nsMenuBarX::ObserveContentRemoved(mozilla::dom::Document* aDocument, nsICon
RemoveMenuAtIndex(index.isSome() ? *index + 1u : 0u);
}
void nsMenuBarX::ObserveContentInserted(mozilla::dom::Document* aDocument, nsIContent* aContainer,
void nsMenuBarX::ObserveContentInserted(mozilla::dom::Document* aDocument,
nsIContent* aContainer,
nsIContent* aChild) {
InsertMenuAtIndex(MakeRefPtr<nsMenuX>(this, mMenuGroupOwner, aChild),
aContainer->ComputeIndexOf(aChild).valueOr(UINT32_MAX));
@ -285,7 +299,8 @@ void nsMenuBarX::ForceUpdateNativeMenuAt(const nsAString& aIndexString) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSString* locationString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(aIndexString.BeginReading())
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(
aIndexString.BeginReading())
length:aIndexString.Length()];
NSArray* indexes = [locationString componentsSeparatedByString:@"|"];
unsigned int indexCount = indexes.count;
@ -329,7 +344,9 @@ void nsMenuBarX::ForceUpdateNativeMenuAt(const nsAString& aIndexString) {
}
RefPtr<nsIContent> content = targetMenu->match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
if (!nsMenuUtilsX::NodeIsHiddenOrCollapsed(content)) {
visible++;
if (targetMenu->is<RefPtr<nsMenuX>>() && visible == (targetIndex + 1)) {
@ -408,8 +425,9 @@ nsresult nsMenuBarX::Paint() {
// We have to keep the same menu item for the Application menu so we keep
// passing it along.
NSMenu* outgoingMenu = NSApp.mainMenu;
NS_ASSERTION(outgoingMenu.numberOfItems > 0,
"Main menu does not have any items, something is terribly wrong!");
NS_ASSERTION(
outgoingMenu.numberOfItems > 0,
"Main menu does not have any items, something is terribly wrong!");
NSMenuItem* appMenuItem = [[outgoingMenu itemAtIndex:0] retain];
[outgoingMenu removeItemAtIndex:0];
@ -456,8 +474,10 @@ bool nsMenuBarX::PerformKeyEquivalent(NSEvent* aEvent) {
return [mNativeMenu performSuperKeyEquivalent:aEvent];
}
void nsMenuBarX::MenuChildChangedVisibility(const MenuChild& aChild, bool aIsVisible) {
MOZ_RELEASE_ASSERT(aChild.is<RefPtr<nsMenuX>>(), "nsMenuBarX only has nsMenuX children");
void nsMenuBarX::MenuChildChangedVisibility(const MenuChild& aChild,
bool aIsVisible) {
MOZ_RELEASE_ASSERT(aChild.is<RefPtr<nsMenuX>>(),
"nsMenuBarX only has nsMenuX children");
const RefPtr<nsMenuX>& child = aChild.as<RefPtr<nsMenuX>>();
NSMenuItem* item = child->NativeNSMenuItem();
if (aIsVisible) {
@ -475,8 +495,9 @@ NSInteger nsMenuBarX::CalculateNativeInsertionPoint(nsMenuX* aChild) {
return insertionPoint;
}
// Only count items that are inside a menu.
// XXXmstange Not sure what would cause free-standing items. Maybe for collapsed/hidden menus?
// In that case, an nsMenuX::IsVisible() method would be better.
// XXXmstange Not sure what would cause free-standing items. Maybe for
// collapsed/hidden menus? In that case, an nsMenuX::IsVisible() method
// would be better.
if (currMenu->NativeNSMenuItem().menu) {
insertionPoint++;
}
@ -486,10 +507,12 @@ NSInteger nsMenuBarX::CalculateNativeInsertionPoint(nsMenuX* aChild) {
// Hide the item in the menu by setting the 'hidden' attribute. Returns it so
// the caller can hang onto it if they so choose.
RefPtr<Element> nsMenuBarX::HideItem(mozilla::dom::Document* aDocument, const nsAString& aID) {
RefPtr<Element> nsMenuBarX::HideItem(mozilla::dom::Document* aDocument,
const nsAString& aID) {
RefPtr<Element> menuElement = aDocument->GetElementById(aID);
if (menuElement) {
menuElement->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, u"true"_ns, false);
menuElement->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden, u"true"_ns,
false);
}
return menuElement;
}
@ -536,7 +559,8 @@ void nsMenuBarX::AquifyMenuBar() {
}
// for creating menu items destined for the Application menu
NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* aMenu, const nsAString& aNodeID,
NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* aMenu,
const nsAString& aNodeID,
SEL aAction, int aTag,
NativeMenuItemTarget* aTarget) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -553,8 +577,8 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* aMenu, const nsAString&
// Check collapsed rather than hidden since the app menu items are always
// hidden in AquifyMenuBar.
if (menuItem->AttrValueIs(kNameSpaceID_None, nsGkAtoms::collapsed, nsGkAtoms::_true,
eCaseMatters)) {
if (menuItem->AttrValueIs(kNameSpaceID_None, nsGkAtoms::collapsed,
nsGkAtoms::_true, eCaseMatters)) {
return nil;
}
@ -577,20 +601,23 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* aMenu, const nsAString&
nsAutoString keyChar(u" "_ns);
keyElement->GetAttr(nsGkAtoms::key, keyChar);
if (!keyChar.EqualsLiteral(" ")) {
keyEquiv = [[NSString stringWithCharacters:reinterpret_cast<const unichar*>(keyChar.get())
length:keyChar.Length()] lowercaseString];
keyEquiv = [[NSString
stringWithCharacters:reinterpret_cast<const unichar*>(keyChar.get())
length:keyChar.Length()] lowercaseString];
}
// now grab the key equivalent modifiers
nsAutoString modifiersStr;
keyElement->GetAttr(nsGkAtoms::modifiers, modifiersStr);
uint8_t geckoModifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
macKeyModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(geckoModifiers);
uint8_t geckoModifiers =
nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
macKeyModifiers =
nsMenuUtilsX::MacModifiersForGeckoModifiers(geckoModifiers);
}
}
// get the label into NSString-form
NSString* labelString =
[NSString stringWithCharacters:reinterpret_cast<const unichar*>(label.get())
length:label.Length()];
NSString* labelString = [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(label.get())
length:label.Length()];
if (!labelString) {
labelString = @"";
@ -634,7 +661,8 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
= Preferences... = <- menu_preferences
= Account Settings = <- menu_accountmgr Only on Thunderbird
========================
= Services > = <- menu_mac_services <- (do not define key equivalent)
= Services > = <- menu_mac_services <- (do not define key
equivalent)
========================
= Hide App = <- menu_mac_hide_app
= Hide Others = <- menu_mac_hide_others
@ -646,34 +674,37 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
========================
If any of them are ommitted from the application's DOM, we just don't add
them. We always add a "Quit" item, but if an app developer does not provide a
DOM node with the right ID for the Quit item, we add it in English. App
developers need only add each node with a label and a key equivalent (if they
want one). Other attributes are optional. Like so:
them. We always add a "Quit" item, but if an app developer does not provide
a DOM node with the right ID for the Quit item, we add it in English. App
developers need only add each node with a label and a key equivalent (if
they want one). Other attributes are optional. Like so:
<menuitem id="menu_preferences"
label="&preferencesCmdMac.label;"
key="open_prefs_key"/>
We need to use this system for localization purposes, until we have a better way
to define the Application menu to be used on Mac OS X.
We need to use this system for localization purposes, until we have a better
way to define the Application menu to be used on Mac OS X.
*/
if (sApplicationMenu) {
if (!mApplicationMenuDelegate) {
mApplicationMenuDelegate = [[ApplicationMenuDelegate alloc] initWithApplicationMenu:this];
mApplicationMenuDelegate =
[[ApplicationMenuDelegate alloc] initWithApplicationMenu:this];
}
sApplicationMenu.delegate = mApplicationMenuDelegate;
// This code reads attributes we are going to care about from the DOM elements
// This code reads attributes we are going to care about from the DOM
// elements
NSMenuItem* itemBeingAdded = nil;
BOOL addAboutSeparator = FALSE;
BOOL addPrefsSeparator = FALSE;
// Add the About menu item
itemBeingAdded = CreateNativeAppMenuItem(aMenu, u"aboutName"_ns, @selector(menuItemHit:),
eCommand_ID_About, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"aboutName"_ns, @selector(menuItemHit:), eCommand_ID_About,
nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -688,8 +719,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add the Preferences menu item
itemBeingAdded = CreateNativeAppMenuItem(aMenu, u"menu_preferences"_ns, @selector(menuItemHit:),
eCommand_ID_Prefs, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_preferences"_ns, @selector(menuItemHit:),
eCommand_ID_Prefs, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -699,8 +731,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add the Account Settings menu item. This is Thunderbird only
itemBeingAdded = CreateNativeAppMenuItem(aMenu, u"menu_accountmgr"_ns, @selector(menuItemHit:),
eCommand_ID_Account, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_accountmgr"_ns, @selector(menuItemHit:),
eCommand_ID_Account, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -713,7 +746,8 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add Services menu item
itemBeingAdded = CreateNativeAppMenuItem(aMenu, u"menu_mac_services"_ns, nil, 0, nil);
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_mac_services"_ns, nil, 0, nil);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
@ -732,9 +766,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
BOOL addHideShowSeparator = FALSE;
// Add menu item to hide this application
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_mac_hide_app"_ns, @selector(menuItemHit:),
eCommand_ID_HideApp, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_mac_hide_app"_ns, @selector(menuItemHit:),
eCommand_ID_HideApp, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -744,9 +778,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add menu item to hide other applications
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_mac_hide_others"_ns, @selector(menuItemHit:),
eCommand_ID_HideOthers, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_mac_hide_others"_ns, @selector(menuItemHit:),
eCommand_ID_HideOthers, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -756,9 +790,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add menu item to show all applications
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_mac_show_all"_ns, @selector(menuItemHit:),
eCommand_ID_ShowAll, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_mac_show_all"_ns, @selector(menuItemHit:),
eCommand_ID_ShowAll, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -775,9 +809,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
BOOL addTouchBarSeparator = NO;
// Add Touch Bar customization menu item.
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_mac_touch_bar"_ns, @selector(menuItemHit:),
eCommand_ID_TouchBar, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_mac_touch_bar"_ns, @selector(menuItemHit:),
eCommand_ID_TouchBar, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
@ -797,9 +831,9 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
}
// Add quit menu item
itemBeingAdded =
CreateNativeAppMenuItem(aMenu, u"menu_FileQuitItem"_ns, @selector(menuItemHit:),
eCommand_ID_Quit, nsMenuBarX::sNativeEventTarget);
itemBeingAdded = CreateNativeAppMenuItem(
aMenu, u"menu_FileQuitItem"_ns, @selector(menuItemHit:),
eCommand_ID_Quit, nsMenuBarX::sNativeEventTarget);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
@ -807,9 +841,10 @@ void nsMenuBarX::CreateApplicationMenu(nsMenuX* aMenu) {
} else {
// the current application does not have a DOM node for "Quit". Add one
// anyway, in English.
NSMenuItem* defaultQuitItem = [[[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(menuItemHit:)
keyEquivalent:@"q"] autorelease];
NSMenuItem* defaultQuitItem =
[[[NSMenuItem alloc] initWithTitle:@"Quit"
action:@selector(menuItemHit:)
keyEquivalent:@"q"] autorelease];
defaultQuitItem.target = nsMenuBarX::sNativeEventTarget;
defaultQuitItem.tag = eCommand_ID_Quit;
[sApplicationMenu addItem:defaultQuitItem];
@ -860,9 +895,9 @@ static BOOL gMenuItemsExecuteCommands = YES;
[super performKeyEquivalent:aEvent];
gMenuItemsExecuteCommands = YES; // return to default
// Return YES if we invoked a command and there is now no key window or we changed
// the first responder. In this case we do not want to propagate the event because
// we don't want it handled again.
// Return YES if we invoked a command and there is now no key window or we
// changed the first responder. In this case we do not want to propagate the
// event because we don't want it handled again.
if (!NSApp.keyWindow || NSApp.keyWindow.firstResponder != firstResponder) {
return YES;
}
@ -898,7 +933,8 @@ static BOOL gMenuItemsExecuteCommands = YES;
nsMenuGroupOwnerX* menuGroupOwner = nullptr;
nsMenuBarX* menuBar = nullptr;
MOZMenuItemRepresentedObject* representedObject = nativeMenuItem.representedObject;
MOZMenuItemRepresentedObject* representedObject =
nativeMenuItem.representedObject;
if (representedObject) {
menuGroupOwner = representedObject.menuGroupOwner;
@ -914,13 +950,15 @@ static BOOL gMenuItemsExecuteCommands = YES;
[(MenuDelegate*)menu.delegate menu:menu willActivateItem:nativeMenuItem];
}
// Get the modifier flags and button for this menu item activation. The menu system does not pass
// an NSEvent to our action selector, but we can query the current NSEvent instead. The current
// NSEvent can be a key event or a mouseup event, depending on how the menu item is activated.
NSEventModifierFlags modifierFlags = NSApp.currentEvent ? NSApp.currentEvent.modifierFlags : 0;
mozilla::MouseButton button = NSApp.currentEvent
? nsCocoaUtils::ButtonForEvent(NSApp.currentEvent)
: mozilla::MouseButton::ePrimary;
// Get the modifier flags and button for this menu item activation. The menu
// system does not pass an NSEvent to our action selector, but we can query
// the current NSEvent instead. The current NSEvent can be a key event or a
// mouseup event, depending on how the menu item is activated.
NSEventModifierFlags modifierFlags =
NSApp.currentEvent ? NSApp.currentEvent.modifierFlags : 0;
mozilla::MouseButton button =
NSApp.currentEvent ? nsCocoaUtils::ButtonForEvent(NSApp.currentEvent)
: mozilla::MouseButton::ePrimary;
// Do special processing if this is for an app-global command.
if (tag == eCommand_ID_About) {
@ -968,13 +1006,15 @@ static BOOL gMenuItemsExecuteCommands = YES;
if (menuBar && menuBar->mQuitItemContent) {
mostSpecificContent = menuBar->mQuitItemContent;
}
// If we have some content for quit we execute it. Otherwise we send a native app terminate
// message. If you want to stop a quit from happening, provide quit content and return
// the event as unhandled.
// If we have some content for quit we execute it. Otherwise we send a
// native app terminate message. If you want to stop a quit from happening,
// provide quit content and return the event as unhandled.
if (mostSpecificContent) {
nsMenuUtilsX::DispatchCommandTo(mostSpecificContent, modifierFlags, button);
nsMenuUtilsX::DispatchCommandTo(mostSpecificContent, modifierFlags,
button);
} else {
nsCOMPtr<nsIAppStartup> appStartup = mozilla::components::AppStartup::Service();
nsCOMPtr<nsIAppStartup> appStartup =
mozilla::components::AppStartup::Service();
if (appStartup) {
bool userAllowedQuit = true;
appStartup->Quit(nsIAppStartup::eAttemptQuit, 0, &userAllowedQuit);
@ -986,12 +1026,13 @@ static BOOL gMenuItemsExecuteCommands = YES;
// given the commandID, look it up in our hashtable and dispatch to
// that menu item.
if (menuGroupOwner) {
if (RefPtr<nsMenuItemX> menuItem =
menuGroupOwner->GetMenuItemForCommandID(static_cast<uint32_t>(tag))) {
if (RefPtr<nsMenuItemX> menuItem = menuGroupOwner->GetMenuItemForCommandID(
static_cast<uint32_t>(tag))) {
if (nsMenuUtilsX::gIsSynchronouslyActivatingNativeMenuItemDuringTest) {
menuItem->DoCommand(modifierFlags, button);
} else if (RefPtr<nsMenuX> menu = menuItem->ParentMenu()) {
menu->ActivateItemAfterClosing(std::move(menuItem), modifierFlags, button);
menu->ActivateItemAfterClosing(std::move(menuItem), modifierFlags,
button);
}
}
}
@ -1041,7 +1082,9 @@ static BOOL gMenuItemsExecuteCommands = YES;
- (NSMenuItem*)addItemWithTitle:(NSString*)aString
action:(SEL)aSelector
keyEquivalent:(NSString*)aKeyEquiv {
NSMenuItem* newItem = [super addItemWithTitle:aString action:aSelector keyEquivalent:aKeyEquiv];
NSMenuItem* newItem = [super addItemWithTitle:aString
action:aSelector
keyEquivalent:aKeyEquiv];
[self _overrideClassOfMenuItem:newItem];
return newItem;
}

Просмотреть файл

@ -26,13 +26,16 @@ using namespace mozilla;
NS_IMPL_ISUPPORTS(nsMenuGroupOwnerX, nsIObserver, nsIMutationObserver)
nsMenuGroupOwnerX::nsMenuGroupOwnerX(mozilla::dom::Element* aElement, nsMenuBarX* aMenuBarIfMenuBar)
nsMenuGroupOwnerX::nsMenuGroupOwnerX(mozilla::dom::Element* aElement,
nsMenuBarX* aMenuBarIfMenuBar)
: mContent(aElement), mMenuBar(aMenuBarIfMenuBar) {
mRepresentedObject = [[MOZMenuItemRepresentedObject alloc] initWithMenuGroupOwner:this];
mRepresentedObject =
[[MOZMenuItemRepresentedObject alloc] initWithMenuGroupOwner:this];
}
nsMenuGroupOwnerX::~nsMenuGroupOwnerX() {
MOZ_ASSERT(mContentToObserverTable.Count() == 0, "have outstanding mutation observers!\n");
MOZ_ASSERT(mContentToObserverTable.Count() == 0,
"have outstanding mutation observers!\n");
[mRepresentedObject setMenuGroupOwner:nullptr];
[mRepresentedObject release];
}
@ -41,11 +44,11 @@ nsMenuGroupOwnerX::~nsMenuGroupOwnerX() {
// nsIMutationObserver
//
void nsMenuGroupOwnerX::CharacterDataWillChange(nsIContent* aContent,
const CharacterDataChangeInfo&) {}
void nsMenuGroupOwnerX::CharacterDataWillChange(
nsIContent* aContent, const CharacterDataChangeInfo&) {}
void nsMenuGroupOwnerX::CharacterDataChanged(nsIContent* aContent, const CharacterDataChangeInfo&) {
}
void nsMenuGroupOwnerX::CharacterDataChanged(nsIContent* aContent,
const CharacterDataChangeInfo&) {}
void nsMenuGroupOwnerX::ContentAppended(nsIContent* aFirstNewContent) {
for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
@ -55,10 +58,13 @@ void nsMenuGroupOwnerX::ContentAppended(nsIContent* aFirstNewContent) {
void nsMenuGroupOwnerX::NodeWillBeDestroyed(nsINode* aNode) {}
void nsMenuGroupOwnerX::AttributeWillChange(dom::Element* aElement, int32_t aNameSpaceID,
nsAtom* aAttribute, int32_t aModType) {}
void nsMenuGroupOwnerX::AttributeWillChange(dom::Element* aElement,
int32_t aNameSpaceID,
nsAtom* aAttribute,
int32_t aModType) {}
void nsMenuGroupOwnerX::AttributeChanged(dom::Element* aElement, int32_t aNameSpaceID,
void nsMenuGroupOwnerX::AttributeChanged(dom::Element* aElement,
int32_t aNameSpaceID,
nsAtom* aAttribute, int32_t aModType,
const nsAttrValue* aOldValue) {
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
@ -68,7 +74,8 @@ void nsMenuGroupOwnerX::AttributeChanged(dom::Element* aElement, int32_t aNameSp
}
}
void nsMenuGroupOwnerX::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling) {
void nsMenuGroupOwnerX::ContentRemoved(nsIContent* aChild,
nsIContent* aPreviousSibling) {
nsIContent* container = aChild->GetParent();
if (!container) {
return;
@ -77,7 +84,8 @@ void nsMenuGroupOwnerX::ContentRemoved(nsIContent* aChild, nsIContent* aPrevious
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
nsChangeObserver* obs = LookupContentChangeObserver(container);
if (obs) {
obs->ObserveContentRemoved(aChild->OwnerDoc(), container, aChild, aPreviousSibling);
obs->ObserveContentRemoved(aChild->OwnerDoc(), container, aChild,
aPreviousSibling);
} else if (container != mContent) {
// We do a lookup on the parent container in case things were removed
// under a "menupopup" item. That is basically a wrapper for the contents
@ -86,7 +94,8 @@ void nsMenuGroupOwnerX::ContentRemoved(nsIContent* aChild, nsIContent* aPrevious
if (parent) {
obs = LookupContentChangeObserver(parent);
if (obs) {
obs->ObserveContentRemoved(aChild->OwnerDoc(), container, aChild, aPreviousSibling);
obs->ObserveContentRemoved(aChild->OwnerDoc(), container, aChild,
aPreviousSibling);
}
}
}
@ -118,18 +127,18 @@ void nsMenuGroupOwnerX::ContentInserted(nsIContent* aChild) {
void nsMenuGroupOwnerX::ParentChainChanged(nsIContent* aContent) {}
void nsMenuGroupOwnerX::ARIAAttributeDefaultWillChange(mozilla::dom::Element* aElement,
nsAtom* aAttribute, int32_t aModType) {}
void nsMenuGroupOwnerX::ARIAAttributeDefaultWillChange(
mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) {}
void nsMenuGroupOwnerX::ARIAAttributeDefaultChanged(mozilla::dom::Element* aElement,
nsAtom* aAttribute, int32_t aModType) {}
void nsMenuGroupOwnerX::ARIAAttributeDefaultChanged(
mozilla::dom::Element* aElement, nsAtom* aAttribute, int32_t aModType) {}
// For change management, we don't use a |nsSupportsHashtable| because
// we know that the lifetime of all these items is bounded by the
// lifetime of the menubar. No need to add any more strong refs to the
// picture because the containment hierarchy already uses strong refs.
void nsMenuGroupOwnerX::RegisterForContentChanges(nsIContent* aContent,
nsChangeObserver* aMenuObject) {
void nsMenuGroupOwnerX::RegisterForContentChanges(
nsIContent* aContent, nsChangeObserver* aMenuObject) {
if (!mContentToObserverTable.Contains(aContent)) {
aContent->AddMutationObserver(this);
}
@ -158,7 +167,8 @@ void nsMenuGroupOwnerX::UnregisterForLocaleChanges() {
}
NS_IMETHODIMP
nsMenuGroupOwnerX::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) {
nsMenuGroupOwnerX::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (mMenuBar && !strcmp(aTopic, "intl:app-locales-changed")) {
// Rebuild the menu with the new locale strings.
mMenuBar->SetNeedsRebuild();
@ -166,7 +176,8 @@ nsMenuGroupOwnerX::Observe(nsISupports* aSubject, const char* aTopic, const char
return NS_OK;
}
nsChangeObserver* nsMenuGroupOwnerX::LookupContentChangeObserver(nsIContent* aContent) {
nsChangeObserver* nsMenuGroupOwnerX::LookupContentChangeObserver(
nsIContent* aContent) {
nsChangeObserver* result;
if (mContentToObserverTable.Get(aContent, &result)) {
return result;
@ -206,7 +217,8 @@ nsMenuItemX* nsMenuGroupOwnerX::GetMenuItemForCommandID(uint32_t aCommandID) {
}
@implementation MOZMenuItemRepresentedObject {
nsMenuGroupOwnerX* mMenuGroupOwner; // weak, cleared by nsMenuGroupOwnerX's destructor
nsMenuGroupOwnerX*
mMenuGroupOwner; // weak, cleared by nsMenuGroupOwnerX's destructor
}
- (id)initWithMenuGroupOwner:(nsMenuGroupOwnerX*)aMenuGroupOwner {

Просмотреть файл

@ -62,8 +62,8 @@ void nsMenuItemIconX::SetupIcon(nsIContent* aContent) {
bool shouldHaveIcon = StartIconLoad(aContent);
if (!shouldHaveIcon) {
// There is no icon for this menu item, as an error occurred while loading it.
// An icon might have been set earlier or the place holder icon may have
// There is no icon for this menu item, as an error occurred while loading
// it. An icon might have been set earlier or the place holder icon may have
// been set. Clear it.
if (mIconImage) {
[mIconImage release];
@ -73,8 +73,9 @@ void nsMenuItemIconX::SetupIcon(nsIContent* aContent) {
}
if (!mIconImage) {
// Set a placeholder icon, so that the menuitem reserves space for the icon during the load and
// there is no sudden shift once the icon finishes loading.
// Set a placeholder icon, so that the menuitem reserves space for the icon
// during the load and there is no sudden shift once the icon finishes
// loading.
NSSize iconSize = NSMakeSize(kIconSize, kIconSize);
mIconImage = [[MOZIconHelper placeholderIconWithSize:iconSize] retain];
}
@ -100,7 +101,8 @@ already_AddRefed<nsIURI> nsMenuItemIconX::GetIconURI(nsIContent* aContent) {
// First, look at the content node's "image" attribute.
nsAutoString imageURIString;
bool hasImageAttr =
aContent->IsElement() && aContent->AsElement()->GetAttr(nsGkAtoms::image, imageURIString);
aContent->IsElement() &&
aContent->AsElement()->GetAttr(nsGkAtoms::image, imageURIString);
if (hasImageAttr) {
// Use the URL from the image attribute.
@ -121,7 +123,8 @@ already_AddRefed<nsIURI> nsMenuItemIconX::GetIconURI(nsIContent* aContent) {
return nullptr;
}
RefPtr<const ComputedStyle> sc = nsComputedDOMStyle::GetComputedStyle(aContent->AsElement());
RefPtr<const ComputedStyle> sc =
nsComputedDOMStyle::GetComputedStyle(aContent->AsElement());
if (!sc) {
return nullptr;
}
@ -149,11 +152,12 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) {
mIconImage = nil;
}
RefPtr<nsPresContext> pc = mPresContext.get();
mIconImage = [[MOZIconHelper iconImageFromImageContainer:aImage
withSize:NSMakeSize(kIconSize, kIconSize)
presContext:pc
computedStyle:mComputedStyle
scaleFactor:0.0f] retain];
mIconImage = [[MOZIconHelper
iconImageFromImageContainer:aImage
withSize:NSMakeSize(kIconSize, kIconSize)
presContext:pc
computedStyle:mComputedStyle
scaleFactor:0.0f] retain];
mComputedStyle = nullptr;
mPresContext = nullptr;

Просмотреть файл

@ -26,14 +26,19 @@ using namespace mozilla;
using mozilla::dom::CallerType;
using mozilla::dom::Event;
nsMenuItemX::nsMenuItemX(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType,
nsMenuItemX::nsMenuItemX(nsMenuX* aParent, const nsString& aLabel,
EMenuItemType aItemType,
nsMenuGroupOwnerX* aMenuGroupOwner, nsIContent* aNode)
: mContent(aNode), mType(aItemType), mMenuParent(aParent), mMenuGroupOwner(aMenuGroupOwner) {
: mContent(aNode),
mType(aItemType),
mMenuParent(aParent),
mMenuGroupOwner(aMenuGroupOwner) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
MOZ_COUNT_CTOR(nsMenuItemX);
MOZ_RELEASE_ASSERT(mContent->IsElement(), "nsMenuItemX should only be created for elements");
MOZ_RELEASE_ASSERT(mContent->IsElement(),
"nsMenuItemX should only be created for elements");
NS_ASSERTION(mMenuGroupOwner, "No menu owner given, must have one!");
mMenuGroupOwner->RegisterForContentChanges(mContent, this);
@ -57,28 +62,29 @@ nsMenuItemX::nsMenuItemX(nsMenuX* aParent, const nsString& aLabel, EMenuItemType
}
}
// decide enabled state based on command content if it exists, otherwise do it based
// on our own content
// decide enabled state based on command content if it exists, otherwise do it
// based on our own content
bool isEnabled;
if (mCommandElement) {
isEnabled = !mCommandElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
nsGkAtoms::_true, eCaseMatters);
isEnabled = !mCommandElement->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters);
} else {
isEnabled = !mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
nsGkAtoms::_true, eCaseMatters);
isEnabled = !mContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters);
}
// set up the native menu item
if (mType == eSeparatorMenuItemType) {
mNativeMenuItem = [[NSMenuItem separatorItem] retain];
} else {
NSString* newCocoaLabelString = nsMenuUtilsX::GetTruncatedCocoaLabel(aLabel);
NSString* newCocoaLabelString =
nsMenuUtilsX::GetTruncatedCocoaLabel(aLabel);
mNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString
action:nil
keyEquivalent:@""];
mIsChecked = mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
nsGkAtoms::_true, eCaseMatters);
mIsChecked = mContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::checked, nsGkAtoms::_true, eCaseMatters);
mNativeMenuItem.enabled = isEnabled;
mNativeMenuItem.state = mIsChecked ? NSOnState : NSOffState;
@ -141,9 +147,11 @@ nsresult nsMenuItemX::SetChecked(bool aIsChecked) {
// update the content model. This will also handle unchecking our siblings
// if we are a radiomenu
if (mIsChecked) {
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::checked, u"true"_ns, true);
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::checked,
u"true"_ns, true);
} else {
mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::checked, true);
mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::checked,
true);
}
// update native menu item
@ -158,10 +166,13 @@ EMenuItemType nsMenuItemX::GetMenuItemType() { return mType; }
// Executes the "cached" javaScript command.
// Returns NS_OK if the command was executed properly, otherwise an error code.
void nsMenuItemX::DoCommand(NSEventModifierFlags aModifierFlags, int16_t aButton) {
void nsMenuItemX::DoCommand(NSEventModifierFlags aModifierFlags,
int16_t aButton) {
// flip "checked" state if we're a checkbox menu, or an un-checked radio menu
if (mType == eCheckboxMenuItemType || (mType == eRadioMenuItemType && !mIsChecked)) {
if (!mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::autocheck,
if (mType == eCheckboxMenuItemType ||
(mType == eRadioMenuItemType && !mIsChecked)) {
if (!mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::autocheck,
nsGkAtoms::_false, eCaseMatters)) {
SetChecked(!mIsChecked);
}
@ -171,7 +182,8 @@ void nsMenuItemX::DoCommand(NSEventModifierFlags aModifierFlags, int16_t aButton
nsMenuUtilsX::DispatchCommandTo(mContent, aModifierFlags, aButton);
}
nsresult nsMenuItemX::DispatchDOMEvent(const nsString& eventName, bool* preventDefaultCalled) {
nsresult nsMenuItemX::DispatchDOMEvent(const nsString& eventName,
bool* preventDefaultCalled) {
if (!mContent) {
return NS_ERROR_FAILURE;
}
@ -181,7 +193,8 @@ nsresult nsMenuItemX::DispatchDOMEvent(const nsString& eventName, bool* preventD
// create DOM event
ErrorResult rv;
RefPtr<Event> event = parentDoc->CreateEvent(u"Events"_ns, CallerType::System, rv);
RefPtr<Event> event =
parentDoc->CreateEvent(u"Events"_ns, CallerType::System, rv);
if (rv.Failed()) {
NS_WARNING("Failed to create Event");
return rv.StealNSResult();
@ -192,7 +205,8 @@ nsresult nsMenuItemX::DispatchDOMEvent(const nsString& eventName, bool* preventD
event->SetTrusted(true);
// send DOM event
*preventDefaultCalled = mContent->DispatchEvent(*event, CallerType::System, rv);
*preventDefaultCalled =
mContent->DispatchEvent(*event, CallerType::System, rv);
if (rv.Failed()) {
NS_WARNING("Failed to send DOM event via EventTarget");
return rv.StealNSResult();
@ -220,9 +234,10 @@ void nsMenuItemX::UncheckRadioSiblings(nsIContent* aCheckedContent) {
sibling = sibling->GetNextSibling()) {
if (sibling != aCheckedContent && sibling->IsElement()) { // skip this node
// if the current sibling is in the same group, clear it
if (sibling->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, myGroupName,
eCaseMatters)) {
sibling->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::checked, u"false"_ns, true);
if (sibling->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
myGroupName, eCaseMatters)) {
sibling->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::checked,
u"false"_ns, true);
}
}
}
@ -236,7 +251,8 @@ void nsMenuItemX::SetKeyEquiv() {
mContent->AsElement()->GetAttr(nsGkAtoms::key, keyValue);
if (!keyValue.IsEmpty() && mContent->GetUncomposedDoc()) {
dom::Element* keyContent = mContent->GetUncomposedDoc()->GetElementById(keyValue);
dom::Element* keyContent =
mContent->GetUncomposedDoc()->GetElementById(keyValue);
if (keyContent) {
nsAutoString keyChar;
bool hasKey = keyContent->GetAttr(nsGkAtoms::key, keyChar);
@ -244,7 +260,8 @@ void nsMenuItemX::SetKeyEquiv() {
if (!hasKey || keyChar.IsEmpty()) {
nsAutoString keyCodeName;
keyContent->GetAttr(nsGkAtoms::keycode, keyCodeName);
uint32_t charCode = nsCocoaUtils::ConvertGeckoNameToMacCharCode(keyCodeName);
uint32_t charCode =
nsCocoaUtils::ConvertGeckoNameToMacCharCode(keyCodeName);
if (charCode) {
keyChar.Assign(charCode);
} else {
@ -254,13 +271,16 @@ void nsMenuItemX::SetKeyEquiv() {
nsAutoString modifiersStr;
keyContent->GetAttr(nsGkAtoms::modifiers, modifiersStr);
uint8_t modifiers = nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
uint8_t modifiers =
nsMenuUtilsX::GeckoModifiersForNodeAttribute(modifiersStr);
unsigned int macModifiers = nsMenuUtilsX::MacModifiersForGeckoModifiers(modifiers);
unsigned int macModifiers =
nsMenuUtilsX::MacModifiersForGeckoModifiers(modifiers);
mNativeMenuItem.keyEquivalentModifierMask = macModifiers;
NSString* keyEquivalent = [[NSString stringWithCharacters:(unichar*)keyChar.get()
length:keyChar.Length()] lowercaseString];
NSString* keyEquivalent =
[[NSString stringWithCharacters:(unichar*)keyChar.get()
length:keyChar.Length()] lowercaseString];
if ([keyEquivalent isEqualToString:@" "]) {
mNativeMenuItem.keyEquivalent = @"";
} else {
@ -279,7 +299,8 @@ void nsMenuItemX::SetKeyEquiv() {
void nsMenuItemX::Dump(uint32_t aIndent) const {
printf("%*s - item [%p] %-16s <%s>\n", aIndent * 2, "", this,
mType == eSeparatorMenuItemType ? "----" : [mNativeMenuItem.title UTF8String],
mType == eSeparatorMenuItemType ? "----"
: [mNativeMenuItem.title UTF8String],
NS_ConvertUTF16toUTF8(mContent->NodeName()).get());
}
@ -287,7 +308,8 @@ void nsMenuItemX::Dump(uint32_t aIndent) const {
// nsChangeObserver
//
void nsMenuItemX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent* aContent,
void nsMenuItemX::ObserveAttributeChanged(dom::Document* aDocument,
nsIContent* aContent,
nsAtom* aAttribute) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -300,17 +322,20 @@ void nsMenuItemX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent*
// if we're a radio menu, uncheck our sibling radio items. No need to
// do any of this if we're just a normal check menu.
if (mType == eRadioMenuItemType &&
mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::checked,
nsGkAtoms::_true, eCaseMatters)) {
UncheckRadioSiblings(mContent);
}
mMenuParent->SetRebuild(true);
} else if (aAttribute == nsGkAtoms::hidden || aAttribute == nsGkAtoms::collapsed) {
} else if (aAttribute == nsGkAtoms::hidden ||
aAttribute == nsGkAtoms::collapsed) {
bool isVisible = !nsMenuUtilsX::NodeIsHiddenOrCollapsed(mContent);
if (isVisible != mIsVisible) {
mIsVisible = isVisible;
RefPtr<nsMenuItemX> self = this;
mMenuParent->MenuChildChangedVisibility(nsMenuParentX::MenuChild(self), isVisible);
mMenuParent->MenuChildChangedVisibility(nsMenuParentX::MenuChild(self),
isVisible);
if (mIsVisible) {
SetupIcon();
}
@ -328,7 +353,8 @@ void nsMenuItemX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent*
SetupIcon();
} else if (aAttribute == nsGkAtoms::disabled) {
mNativeMenuItem.enabled = !aContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters);
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true,
eCaseMatters);
}
} else if (aContent == mCommandElement) {
// the only thing that really matters when the menu isn't showing is the
@ -342,15 +368,17 @@ void nsMenuItemX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent*
if (!commandDisabled.Equals(menuDisabled)) {
// The menu's disabled state needs to be updated to match the command.
if (commandDisabled.IsEmpty()) {
mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
mContent->AsElement()->UnsetAttr(kNameSpaceID_None,
nsGkAtoms::disabled, true);
} else {
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, commandDisabled,
true);
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
commandDisabled, true);
}
}
// now we sync our native menu item with the command DOM node
mNativeMenuItem.enabled = !aContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters);
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true,
eCaseMatters);
}
}
@ -362,8 +390,10 @@ bool IsMenuStructureElement(nsIContent* aContent) {
nsGkAtoms::menuseparator);
}
void nsMenuItemX::ObserveContentRemoved(dom::Document* aDocument, nsIContent* aContainer,
nsIContent* aChild, nsIContent* aPreviousSibling) {
void nsMenuItemX::ObserveContentRemoved(dom::Document* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
nsIContent* aPreviousSibling) {
MOZ_RELEASE_ASSERT(mMenuGroupOwner);
MOZ_RELEASE_ASSERT(mMenuParent);
@ -376,7 +406,8 @@ void nsMenuItemX::ObserveContentRemoved(dom::Document* aDocument, nsIContent* aC
}
}
void nsMenuItemX::ObserveContentInserted(dom::Document* aDocument, nsIContent* aContainer,
void nsMenuItemX::ObserveContentInserted(dom::Document* aDocument,
nsIContent* aContainer,
nsIContent* aChild) {
MOZ_RELEASE_ASSERT(mMenuParent);
@ -390,7 +421,8 @@ void nsMenuItemX::ObserveContentInserted(dom::Document* aDocument, nsIContent* a
void nsMenuItemX::SetupIcon() {
if (mType != eRegularMenuItemType) {
// Don't support icons on checkbox and radio menuitems, for consistency with Windows & Linux.
// Don't support icons on checkbox and radio menuitems, for consistency with
// Windows & Linux.
return;
}
@ -398,4 +430,6 @@ void nsMenuItemX::SetupIcon() {
mNativeMenuItem.image = mIcon->GetIconImage();
}
void nsMenuItemX::IconUpdated() { mNativeMenuItem.image = mIcon->GetIconImage(); }
void nsMenuItemX::IconUpdated() {
mNativeMenuItem.image = mIcon->GetIconImage();
}

Просмотреть файл

@ -28,7 +28,8 @@ using namespace mozilla;
bool nsMenuUtilsX::gIsSynchronouslyActivatingNativeMenuItemDuringTest = false;
void nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent,
NSEventModifierFlags aModifierFlags, int16_t aButton) {
NSEventModifierFlags aModifierFlags,
int16_t aButton) {
MOZ_ASSERT(aTargetContent, "null ptr");
dom::Document* doc = aTargetContent->OwnerDoc();
@ -43,8 +44,9 @@ void nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent,
IgnoredErrorResult rv;
event->InitCommandEvent(u"command"_ns, true, true,
nsGlobalWindowInner::Cast(doc->GetInnerWindow()), 0, ctrlKey, altKey,
shiftKey, cmdKey, aButton, nullptr, 0, rv);
nsGlobalWindowInner::Cast(doc->GetInnerWindow()), 0,
ctrlKey, altKey, shiftKey, cmdKey, aButton, nullptr,
0, rv);
if (!rv.Failed()) {
event->SetTrusted(true);
aTargetContent->DispatchEvent(*event);
@ -55,17 +57,19 @@ void nsMenuUtilsX::DispatchCommandTo(nsIContent* aTargetContent,
NSString* nsMenuUtilsX::GetTruncatedCocoaLabel(const nsString& itemLabel) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
// We want to truncate long strings to some reasonable pixel length but there is no
// good API for doing that which works for all OS versions and architectures. For now
// we'll do nothing for consistency and depend on good user interface design to limit
// string lengths.
return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(itemLabel.get())
length:itemLabel.Length()];
// We want to truncate long strings to some reasonable pixel length but there
// is no good API for doing that which works for all OS versions and
// architectures. For now we'll do nothing for consistency and depend on good
// user interface design to limit string lengths.
return [NSString
stringWithCharacters:reinterpret_cast<const unichar*>(itemLabel.get())
length:itemLabel.Length()];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
uint8_t nsMenuUtilsX::GeckoModifiersForNodeAttribute(const nsString& modifiersAttribute) {
uint8_t nsMenuUtilsX::GeckoModifiersForNodeAttribute(
const nsString& modifiersAttribute) {
uint8_t modifiers = knsMenuItemNoModifier;
char* str = ToNewCString(modifiersAttribute);
char* newStr;
@ -87,7 +91,8 @@ uint8_t nsMenuUtilsX::GeckoModifiersForNodeAttribute(const nsString& modifiersAt
return modifiers;
}
unsigned int nsMenuUtilsX::MacModifiersForGeckoModifiers(uint8_t geckoModifiers) {
unsigned int nsMenuUtilsX::MacModifiersForGeckoModifiers(
uint8_t geckoModifiers) {
unsigned int macModifiers = 0;
if (geckoModifiers & knsMenuItemShiftModifier) {
@ -109,7 +114,8 @@ unsigned int nsMenuUtilsX::MacModifiersForGeckoModifiers(uint8_t geckoModifiers)
nsMenuBarX* nsMenuUtilsX::GetHiddenWindowMenuBar() {
nsIWidget* hiddenWindowWidgetNoCOMPtr = nsCocoaUtils::GetHiddenWindowWidget();
if (hiddenWindowWidgetNoCOMPtr) {
return static_cast<nsCocoaWindow*>(hiddenWindowWidgetNoCOMPtr)->GetMenuBar();
return static_cast<nsCocoaWindow*>(hiddenWindowWidgetNoCOMPtr)
->GetMenuBar();
}
return nullptr;
}
@ -123,9 +129,9 @@ NSMenuItem* nsMenuUtilsX::GetStandardEditMenuItem() {
// app-modal dialogs and Gecko-modal dialogs that open above them. So what
// we return here isn't always released before it needs to be added to
// another menu. See bmo bug 468393.
NSMenuItem* standardEditMenuItem = [[[NSMenuItem alloc] initWithTitle:@"Edit"
action:nil
keyEquivalent:@""] autorelease];
NSMenuItem* standardEditMenuItem =
[[[NSMenuItem alloc] initWithTitle:@"Edit" action:nil
keyEquivalent:@""] autorelease];
NSMenu* standardEditMenu = [[NSMenu alloc] initWithTitle:@"Edit"];
standardEditMenuItem.submenu = standardEditMenu;
[standardEditMenu release];
@ -176,9 +182,10 @@ NSMenuItem* nsMenuUtilsX::GetStandardEditMenuItem() {
[deleteItem release];
// Add Select All
NSMenuItem* selectAllItem = [[NSMenuItem alloc] initWithTitle:@"Select All"
action:@selector(selectAll:)
keyEquivalent:@"a"];
NSMenuItem* selectAllItem =
[[NSMenuItem alloc] initWithTitle:@"Select All"
action:@selector(selectAll:)
keyEquivalent:@"a"];
[standardEditMenu addItem:selectAllItem];
[selectAllItem release];
@ -188,16 +195,19 @@ NSMenuItem* nsMenuUtilsX::GetStandardEditMenuItem() {
}
bool nsMenuUtilsX::NodeIsHiddenOrCollapsed(nsIContent* aContent) {
return aContent->IsElement() &&
(aContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden, nsGkAtoms::_true,
eCaseMatters) ||
aContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::collapsed,
nsGkAtoms::_true, eCaseMatters));
return aContent->IsElement() && (aContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::hidden,
nsGkAtoms::_true, eCaseMatters) ||
aContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::collapsed,
nsGkAtoms::_true, eCaseMatters));
}
NSMenuItem* nsMenuUtilsX::NativeMenuItemWithLocation(NSMenu* aRootMenu, NSString* aLocationString,
NSMenuItem* nsMenuUtilsX::NativeMenuItemWithLocation(NSMenu* aRootMenu,
NSString* aLocationString,
bool aIsMenuBar) {
NSArray<NSString*>* indexes = [aLocationString componentsSeparatedByString:@"|"];
NSArray<NSString*>* indexes =
[aLocationString componentsSeparatedByString:@"|"];
unsigned int pathLength = indexes.count;
if (pathLength == 0) {
return nil;
@ -207,7 +217,8 @@ NSMenuItem* nsMenuUtilsX::NativeMenuItemWithLocation(NSMenu* aRootMenu, NSString
for (unsigned int depth = 0; depth < pathLength; depth++) {
NSInteger targetIndex = [indexes objectAtIndex:depth].integerValue;
if (aIsMenuBar && depth == 0) {
// We remove the application menu from consideration for the top-level menu.
// We remove the application menu from consideration for the top-level
// menu.
targetIndex++;
}
int itemCount = currentSubmenu.numberOfItems;
@ -230,20 +241,24 @@ NSMenuItem* nsMenuUtilsX::NativeMenuItemWithLocation(NSMenu* aRootMenu, NSString
return nil;
}
static void CheckNativeMenuConsistencyImpl(NSMenu* aMenu, std::unordered_set<void*>& aSeenObjects);
static void CheckNativeMenuConsistencyImpl(
NSMenu* aMenu, std::unordered_set<void*>& aSeenObjects);
static void CheckNativeMenuItemConsistencyImpl(NSMenuItem* aMenuItem,
std::unordered_set<void*>& aSeenObjects) {
static void CheckNativeMenuItemConsistencyImpl(
NSMenuItem* aMenuItem, std::unordered_set<void*>& aSeenObjects) {
bool inserted = aSeenObjects.insert(aMenuItem).second;
MOZ_RELEASE_ASSERT(inserted, "Duplicate NSMenuItem object in native menu structure");
MOZ_RELEASE_ASSERT(inserted,
"Duplicate NSMenuItem object in native menu structure");
if (aMenuItem.hasSubmenu) {
CheckNativeMenuConsistencyImpl(aMenuItem.submenu, aSeenObjects);
}
}
static void CheckNativeMenuConsistencyImpl(NSMenu* aMenu, std::unordered_set<void*>& aSeenObjects) {
static void CheckNativeMenuConsistencyImpl(
NSMenu* aMenu, std::unordered_set<void*>& aSeenObjects) {
bool inserted = aSeenObjects.insert(aMenu).second;
MOZ_RELEASE_ASSERT(inserted, "Duplicate NSMenu object in native menu structure");
MOZ_RELEASE_ASSERT(inserted,
"Duplicate NSMenu object in native menu structure");
for (NSMenuItem* item in aMenu.itemArray) {
CheckNativeMenuItemConsistencyImpl(item, aSeenObjects);
}
@ -278,16 +293,20 @@ static void DumpNativeNSMenuItemImpl(NSMenuItem* aItem, uint32_t aIndent,
if (aIndexInParentMenu) {
printf("[%d] ", *aIndexInParentMenu);
}
printf("NSMenuItem [%p] %-16s%s\n", aItem,
aItem.isSeparatorItem ? "----"
: (aItem.title.length == 0 ? "(no title)" : aItem.title.UTF8String),
aItem.hasSubmenu ? " [hasSubmenu]" : "");
printf(
"NSMenuItem [%p] %-16s%s\n", aItem,
aItem.isSeparatorItem
? "----"
: (aItem.title.length == 0 ? "(no title)" : aItem.title.UTF8String),
aItem.hasSubmenu ? " [hasSubmenu]" : "");
if (aItem.hasSubmenu) {
DumpNativeNSMenuImpl(aItem.submenu, aIndent + 1);
}
}
void nsMenuUtilsX::DumpNativeMenu(NSMenu* aMenu) { DumpNativeNSMenuImpl(aMenu, 0); }
void nsMenuUtilsX::DumpNativeMenu(NSMenu* aMenu) {
DumpNativeNSMenuImpl(aMenu, 0);
}
void nsMenuUtilsX::DumpNativeMenuItem(NSMenuItem* aMenuItem) {
DumpNativeNSMenuItemImpl(aMenuItem, 0, Nothing());

Просмотреть файл

@ -57,20 +57,25 @@ static void SwizzleDynamicIndexingMethods() {
nsToolkit::SwizzleMethods([NSMenu class], @selector(_addItem:toTable:),
@selector(nsMenuX_NSMenu_addItem:toTable:), true);
nsToolkit::SwizzleMethods([NSMenu class], @selector(_removeItem:fromTable:),
@selector(nsMenuX_NSMenu_removeItem:fromTable:), true);
@selector(nsMenuX_NSMenu_removeItem:fromTable:),
true);
// On SnowLeopard the Shortcut framework (which contains the
// SCTGRLIndex class) is loaded on demand, whenever the user first opens
// a menu (which normally hasn't happened yet). So we need to load it
// here explicitly.
dlopen("/System/Library/PrivateFrameworks/Shortcut.framework/Shortcut", RTLD_LAZY);
dlopen("/System/Library/PrivateFrameworks/Shortcut.framework/Shortcut",
RTLD_LAZY);
Class SCTGRLIndexClass = ::NSClassFromString(@"SCTGRLIndex");
nsToolkit::SwizzleMethods(SCTGRLIndexClass, @selector(indexMenuBarDynamically),
@selector(nsMenuX_SCTGRLIndex_indexMenuBarDynamically));
nsToolkit::SwizzleMethods(
SCTGRLIndexClass, @selector(indexMenuBarDynamically),
@selector(nsMenuX_SCTGRLIndex_indexMenuBarDynamically));
Class NSServicesMenuUpdaterClass = ::NSClassFromString(@"_NSServicesMenuUpdater");
nsToolkit::SwizzleMethods(NSServicesMenuUpdaterClass,
@selector(populateMenu:withServiceEntries:forDisplay:),
@selector(nsMenuX_populateMenu:withServiceEntries:forDisplay:));
Class NSServicesMenuUpdaterClass =
::NSClassFromString(@"_NSServicesMenuUpdater");
nsToolkit::SwizzleMethods(
NSServicesMenuUpdaterClass,
@selector(populateMenu:withServiceEntries:forDisplay:),
@selector(nsMenuX_populateMenu:withServiceEntries:forDisplay:));
gMenuMethodsSwizzled = true;
}
@ -79,7 +84,8 @@ static void SwizzleDynamicIndexingMethods() {
// nsMenuX
//
nsMenuX::nsMenuX(nsMenuParentX* aParent, nsMenuGroupOwnerX* aMenuGroupOwner, nsIContent* aContent)
nsMenuX::nsMenuX(nsMenuParentX* aParent, nsMenuGroupOwnerX* aMenuGroupOwner,
nsIContent* aContent)
: mContent(aContent), mParent(aParent), mMenuGroupOwner(aMenuGroupOwner) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -98,7 +104,8 @@ nsMenuX::nsMenuX(nsMenuParentX* aParent, nsMenuGroupOwnerX* aMenuGroupOwner, nsI
}
mNativeMenu = CreateMenuWithGeckoString(mLabel);
// register this menu to be notified when changes are made to our content object
// register this menu to be notified when changes are made to our content
// object
NS_ASSERTION(mMenuGroupOwner, "No menu owner given, must have one");
mMenuGroupOwner->RegisterForContentChanges(mContent, this);
@ -111,8 +118,9 @@ nsMenuX::nsMenuX(nsMenuParentX* aParent, nsMenuGroupOwnerX* aMenuGroupOwner, nsI
mNativeMenuItem.submenu = mNativeMenu;
SetEnabled(!mContent->IsElement() ||
!mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
nsGkAtoms::_true, eCaseMatters));
!mContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true,
eCaseMatters));
// We call RebuildMenu here because keyboard commands are dependent upon
// native menu items being created. If we only call RebuildMenu when a menu
@ -168,8 +176,9 @@ nsMenuX::~nsMenuX() {
void nsMenuX::DetachFromGroupOwnerRecursive() {
if (!mMenuGroupOwner) {
// Don't recurse if this subtree is already detached.
// This avoids repeated recursion during the destruction of nested nsMenuX structures.
// Our invariant is: If we are detached, all of our contents are also detached.
// This avoids repeated recursion during the destruction of nested nsMenuX
// structures. Our invariant is: If we are detached, all of our contents are
// also detached.
return;
}
@ -180,8 +189,13 @@ void nsMenuX::DetachFromGroupOwnerRecursive() {
// Also detach all our children.
for (auto& child : mMenuChildren) {
child.match([](const RefPtr<nsMenuX>& aMenu) { aMenu->DetachFromGroupOwnerRecursive(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { aMenuItem->DetachFromGroupOwner(); });
child.match(
[](const RefPtr<nsMenuX>& aMenu) {
aMenu->DetachFromGroupOwnerRecursive();
},
[](const RefPtr<nsMenuItemX>& aMenuItem) {
aMenuItem->DetachFromGroupOwner();
});
}
}
@ -199,7 +213,8 @@ void nsMenuX::OnMenuDidOpen(dom::Element* aPopupElement) {
}
}
void nsMenuX::OnMenuWillActivateItem(dom::Element* aPopupElement, dom::Element* aMenuItemElement) {
void nsMenuX::OnMenuWillActivateItem(dom::Element* aPopupElement,
dom::Element* aMenuItemElement) {
RefPtr<nsMenuX> kungFuDeathGrip(this);
if (mObserver) {
mObserver->OnMenuWillActivateItem(aPopupElement, aMenuItemElement);
@ -219,12 +234,16 @@ void nsMenuX::AddMenuChild(MenuChild&& aChild) {
WillInsertChild(aChild);
mMenuChildren.AppendElement(aChild);
bool isVisible =
aChild.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->IsVisible(); });
bool isVisible = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->IsVisible();
});
NSMenuItem* nativeItem = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->NativeNSMenuItem(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->NativeNSMenuItem(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->NativeNSMenuItem();
});
if (isVisible) {
RemovePlaceholderIfPresent();
@ -242,9 +261,11 @@ void nsMenuX::InsertMenuChild(MenuChild&& aChild) {
size_t insertionIndex = FindInsertionIndex(aChild);
mMenuChildren.InsertElementAt(insertionIndex, aChild);
bool isVisible =
aChild.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->IsVisible(); });
bool isVisible = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->IsVisible();
});
if (isVisible) {
MenuChildChangedVisibility(aChild, true);
}
@ -253,9 +274,11 @@ void nsMenuX::InsertMenuChild(MenuChild&& aChild) {
}
void nsMenuX::RemoveMenuChild(const MenuChild& aChild) {
bool isVisible =
aChild.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->IsVisible(); });
bool isVisible = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->IsVisible(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->IsVisible();
});
if (isVisible) {
MenuChildChangedVisibility(aChild, false);
}
@ -268,16 +291,20 @@ size_t nsMenuX::FindInsertionIndex(const MenuChild& aChild) {
nsCOMPtr<nsIContent> menuPopup = GetMenuPopupContent();
MOZ_RELEASE_ASSERT(menuPopup);
RefPtr<nsIContent> insertedContent =
aChild.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
RefPtr<nsIContent> insertedContent = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
MOZ_RELEASE_ASSERT(insertedContent->GetParent() == menuPopup);
// Iterate over menuPopup's children (insertedContent's siblings) until we encounter
// insertedContent. At the same time, keep track of the index in mMenuChildren.
// Iterate over menuPopup's children (insertedContent's siblings) until we
// encounter insertedContent. At the same time, keep track of the index in
// mMenuChildren.
size_t index = 0;
for (nsIContent* child = menuPopup->GetFirstChild(); child && index < mMenuChildren.Length();
for (nsIContent* child = menuPopup->GetFirstChild();
child && index < mMenuChildren.Length();
child = child->GetNextSibling()) {
if (child == insertedContent) {
break;
@ -285,7 +312,9 @@ size_t nsMenuX::FindInsertionIndex(const MenuChild& aChild) {
RefPtr<nsIContent> contentAtIndex = mMenuChildren[index].match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
if (child == contentAtIndex) {
index++;
}
@ -313,7 +342,8 @@ nsresult nsMenuX::GetVisibleItemCount(uint32_t& aCount) {
}
// Only includes visible items. Note that this is provides O(N) access
// If you need to iterate or search, consider using GetItemAt and doing your own filtering
// If you need to iterate or search, consider using GetItemAt and doing your own
// filtering
Maybe<nsMenuX::MenuChild> nsMenuX::GetVisibleItemAt(uint32_t aPos) {
uint32_t count = mMenuChildren.Length();
if (aPos >= mVisibleItemsCount || aPos >= count) {
@ -329,9 +359,11 @@ Maybe<nsMenuX::MenuChild> nsMenuX::GetVisibleItemAt(uint32_t aPos) {
uint32_t visibleNodeIndex = 0;
for (uint32_t i = 0; i < count; i++) {
MenuChild item = *GetItemAt(i);
RefPtr<nsIContent> content =
item.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
RefPtr<nsIContent> content = item.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
if (!nsMenuUtilsX::NodeIsHiddenOrCollapsed(content)) {
if (aPos == visibleNodeIndex) {
// we found the visible node we're looking for, return it
@ -344,11 +376,14 @@ Maybe<nsMenuX::MenuChild> nsMenuX::GetVisibleItemAt(uint32_t aPos) {
return {};
}
Maybe<nsMenuX::MenuChild> nsMenuX::GetItemForElement(Element* aMenuChildElement) {
Maybe<nsMenuX::MenuChild> nsMenuX::GetItemForElement(
Element* aMenuChildElement) {
for (auto& child : mMenuChildren) {
RefPtr<nsIContent> content =
child.match([](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->Content(); });
RefPtr<nsIContent> content = child.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->Content(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->Content();
});
if (content == aMenuChildElement) {
return Some(child);
}
@ -397,7 +432,8 @@ void nsMenuX::MenuOpened() {
return;
}
// Make sure we fire any pending popupshown / popuphiding / popuphidden events first.
// Make sure we fire any pending popupshown / popuphiding / popuphidden events
// first.
FlushMenuOpenedRunnable();
FlushMenuClosedRunnable();
@ -405,10 +441,11 @@ void nsMenuX::MenuOpened() {
// Fire popupshowing now.
bool approvedToOpen = OnOpen();
if (!approvedToOpen) {
// We can only stop menus from opening which we open ourselves. We cannot stop menubar root
// menus or menu submenus from opening.
// For context menus, we can call OnOpen() before we ask the system to open the menu.
NS_WARNING("The popupshowing event had preventDefault() called on it, but in MenuOpened() it "
// We can only stop menus from opening which we open ourselves. We cannot
// stop menubar root menus or menu submenus from opening. For context
// menus, we can call OnOpen() before we ask the system to open the menu.
NS_WARNING("The popupshowing event had preventDefault() called on it, "
"but in MenuOpened() it "
"is too late to stop the menu from opening.");
}
}
@ -425,10 +462,9 @@ void nsMenuX::MenuOpened() {
}
// Fire the popupshown event in MenuOpenedAsync.
// MenuOpened() is called during menuWillOpen, and if cancelTracking is called now, menuDidClose
// will not be called.
// The runnable object must not hold a strong reference to the nsMenuX, so that there is no
// reference cycle.
// MenuOpened() is called during menuWillOpen, and if cancelTracking is called
// now, menuDidClose will not be called. The runnable object must not hold a
// strong reference to the nsMenuX, so that there is no reference cycle.
class MenuOpenedAsyncRunnable final : public mozilla::CancelableRunnable {
public:
explicit MenuOpenedAsyncRunnable(nsMenuX* aMenu)
@ -470,7 +506,8 @@ void nsMenuX::MenuOpenedAsync() {
// Open the node.
if (mContent->IsElement()) {
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::open, u"true"_ns, true);
mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::open,
u"true"_ns, true);
}
RefPtr<nsIContent> popupContent = GetMenuPopupContent();
@ -482,7 +519,8 @@ void nsMenuX::MenuOpenedAsync() {
// Fire popupshown.
nsEventStatus status = nsEventStatus_eIgnore;
WidgetMouseEvent event(true, eXULPopupShown, nullptr, WidgetMouseEvent::eReal);
WidgetMouseEvent event(true, eXULPopupShown, nullptr,
WidgetMouseEvent::eReal);
RefPtr<nsIContent> dispatchTo = popupContent ? popupContent : mContent;
EventDispatcher::Dispatch(dispatchTo, nullptr, &event, nullptr, &status);
}
@ -495,7 +533,8 @@ void nsMenuX::MenuClosed() {
// Make sure we fire any pending popupshown events first.
FlushMenuOpenedRunnable();
// If any of our submenus were opened programmatically, make sure they get closed first.
// If any of our submenus were opened programmatically, make sure they get
// closed first.
for (auto& child : mMenuChildren) {
if (child.is<RefPtr<nsMenuX>>()) {
child.as<RefPtr<nsMenuX>>()->MenuClosed();
@ -505,11 +544,11 @@ void nsMenuX::MenuClosed() {
mIsOpen = false;
// Do the rest of the MenuClosed work in MenuClosedAsync.
// MenuClosed() is called from -[NSMenuDelegate menuDidClose:]. If a menuitem was clicked,
// menuDidClose is called *before* menuItemHit for the clicked menu item is called.
// This runnable will be canceled if ~nsMenuX runs before the runnable.
// The runnable object must not hold a strong reference to the nsMenuX, so that there is no
// reference cycle.
// MenuClosed() is called from -[NSMenuDelegate menuDidClose:]. If a menuitem
// was clicked, menuDidClose is called *before* menuItemHit for the clicked
// menu item is called. This runnable will be canceled if ~nsMenuX runs before
// the runnable. The runnable object must not hold a strong reference to the
// nsMenuX, so that there is no reference cycle.
class MenuClosedAsyncRunnable final : public mozilla::CancelableRunnable {
public:
explicit MenuClosedAsyncRunnable(nsMenuX* aMenu)
@ -538,7 +577,8 @@ void nsMenuX::MenuClosed() {
}
void nsMenuX::FlushMenuClosedRunnable() {
// If any of our submenus have a pending menu closed runnable, make sure those run first.
// If any of our submenus have a pending menu closed runnable, make sure those
// run first.
for (auto& child : mMenuChildren) {
if (child.is<RefPtr<nsMenuX>>()) {
child.as<RefPtr<nsMenuX>>()->FlushMenuClosedRunnable();
@ -569,8 +609,10 @@ void nsMenuX::MenuClosedAsync() {
nsCOMPtr<nsIContent> dispatchTo = popupContent ? popupContent : mContent;
nsEventStatus status = nsEventStatus_eIgnore;
WidgetMouseEvent popupHiding(true, eXULPopupHiding, nullptr, WidgetMouseEvent::eReal);
EventDispatcher::Dispatch(dispatchTo, nullptr, &popupHiding, nullptr, &status);
WidgetMouseEvent popupHiding(true, eXULPopupHiding, nullptr,
WidgetMouseEvent::eReal);
EventDispatcher::Dispatch(dispatchTo, nullptr, &popupHiding, nullptr,
&status);
mIsOpenForGecko = false;
@ -578,8 +620,10 @@ void nsMenuX::MenuClosedAsync() {
mContent->AsElement()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::open, true);
}
WidgetMouseEvent popupHidden(true, eXULPopupHidden, nullptr, WidgetMouseEvent::eReal);
EventDispatcher::Dispatch(dispatchTo, nullptr, &popupHidden, nullptr, &status);
WidgetMouseEvent popupHidden(true, eXULPopupHidden, nullptr,
WidgetMouseEvent::eReal);
EventDispatcher::Dispatch(dispatchTo, nullptr, &popupHidden, nullptr,
&status);
// Notify our observer.
if (mObserver && popupContent) {
@ -587,17 +631,22 @@ void nsMenuX::MenuClosedAsync() {
}
}
void nsMenuX::ActivateItemAfterClosing(RefPtr<nsMenuItemX>&& aItem, NSEventModifierFlags aModifiers,
void nsMenuX::ActivateItemAfterClosing(RefPtr<nsMenuItemX>&& aItem,
NSEventModifierFlags aModifiers,
int16_t aButton) {
if (mIsOpenForGecko) {
// Queue the event into mPendingCommandEvents. We will call aItem->DoCommand in
// MenuClosedAsync(). We rely on the assumption that MenuClosedAsync will run soon.
mPendingCommandEvents.AppendElement(PendingCommandEvent{std::move(aItem), aModifiers, aButton});
// Queue the event into mPendingCommandEvents. We will call aItem->DoCommand
// in MenuClosedAsync(). We rely on the assumption that MenuClosedAsync will
// run soon.
mPendingCommandEvents.AppendElement(
PendingCommandEvent{std::move(aItem), aModifiers, aButton});
} else {
// The menu item was activated outside of a regular open / activate / close sequence.
// This happens in multiple cases:
// - When a menu item is activated by a keyboard shortcut while all windows are closed
// (otherwise those shortcuts go through Gecko's manual keyboard handling)
// The menu item was activated outside of a regular open / activate / close
// sequence. This happens in multiple cases:
// - When a menu item is activated by a keyboard shortcut while all windows
// are closed
// (otherwise those shortcuts go through Gecko's manual keyboard
// handling)
// - When a menu item in the Dock menu is clicked
// - During native menu tests
//
@ -610,10 +659,11 @@ bool nsMenuX::Close() {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (mDidFirePopupshowingAndIsApprovedToOpen && !mIsOpen) {
// Close is being called right after this menu was opened, but before MenuOpened() had a chance
// to run. Call it here so that we can go through the entire popupshown -> popuphiding ->
// popuphidden sequence. Some callers expect to get a popuphidden event even if they close the
// popup before it was fully open.
// Close is being called right after this menu was opened, but before
// MenuOpened() had a chance to run. Call it here so that we can go through
// the entire popupshown -> popuphiding -> popuphidden sequence. Some
// callers expect to get a popuphidden event even if they close the popup
// before it was fully open.
MenuOpened();
}
@ -623,11 +673,12 @@ bool nsMenuX::Close() {
if (mIsOpen) {
// Close the menu.
// We usually don't get here during normal Firefox usage: If the user closes the menu by
// clicking an item, or by clicking outside the menu, or by pressing escape, then the menu gets
// closed by macOS, and not by a call to nsMenuX::Close().
// If we do get here, it's usually because we're running an automated test. Close the menu
// without the fade-out animation so that we don't unnecessarily slow down the automated tests.
// We usually don't get here during normal Firefox usage: If the user closes
// the menu by clicking an item, or by clicking outside the menu, or by
// pressing escape, then the menu gets closed by macOS, and not by a call to
// nsMenuX::Close(). If we do get here, it's usually because we're running
// an automated test. Close the menu without the fade-out animation so that
// we don't unnecessarily slow down the automated tests.
[mNativeMenu cancelTrackingWithoutAnimation];
MOZMenuOpeningCoordinator.needToUnwindForMenuClosing = YES;
@ -642,7 +693,8 @@ bool nsMenuX::Close() {
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsMenuX::OnHighlightedItemChanged(const Maybe<uint32_t>& aNewHighlightedIndex) {
void nsMenuX::OnHighlightedItemChanged(
const Maybe<uint32_t>& aNewHighlightedIndex) {
if (mHighlightedItemIndex == aNewHighlightedIndex) {
return;
}
@ -651,16 +703,16 @@ void nsMenuX::OnHighlightedItemChanged(const Maybe<uint32_t>& aNewHighlightedInd
Maybe<nsMenuX::MenuChild> target = GetVisibleItemAt(*mHighlightedItemIndex);
if (target && target->is<RefPtr<nsMenuItemX>>()) {
bool handlerCalledPreventDefault; // but we don't actually care
target->as<RefPtr<nsMenuItemX>>()->DispatchDOMEvent(u"DOMMenuItemInactive"_ns,
&handlerCalledPreventDefault);
target->as<RefPtr<nsMenuItemX>>()->DispatchDOMEvent(
u"DOMMenuItemInactive"_ns, &handlerCalledPreventDefault);
}
}
if (aNewHighlightedIndex) {
Maybe<nsMenuX::MenuChild> target = GetVisibleItemAt(*aNewHighlightedIndex);
if (target && target->is<RefPtr<nsMenuItemX>>()) {
bool handlerCalledPreventDefault; // but we don't actually care
target->as<RefPtr<nsMenuItemX>>()->DispatchDOMEvent(u"DOMMenuItemActive"_ns,
&handlerCalledPreventDefault);
target->as<RefPtr<nsMenuItemX>>()->DispatchDOMEvent(
u"DOMMenuItemActive"_ns, &handlerCalledPreventDefault);
}
}
mHighlightedItemIndex = aNewHighlightedIndex;
@ -672,21 +724,25 @@ void nsMenuX::OnWillActivateItem(NSMenuItem* aItem) {
}
if (mMenuGroupOwner && mObserver) {
nsMenuItemX* item = mMenuGroupOwner->GetMenuItemForCommandID(uint32_t(aItem.tag));
nsMenuItemX* item =
mMenuGroupOwner->GetMenuItemForCommandID(uint32_t(aItem.tag));
if (item && item->Content()->IsElement()) {
RefPtr<dom::Element> itemElement = item->Content()->AsElement();
if (nsCOMPtr<nsIContent> popupContent = GetMenuPopupContent()) {
mObserver->OnMenuWillActivateItem(popupContent->AsElement(), itemElement);
mObserver->OnMenuWillActivateItem(popupContent->AsElement(),
itemElement);
}
}
}
}
// Flushes style.
static NSUserInterfaceLayoutDirection DirectionForElement(dom::Element* aElement) {
// Get the direction from the computed style so that inheritance into submenus is respected.
// aElement may not have a frame.
RefPtr<const ComputedStyle> sc = nsComputedDOMStyle::GetComputedStyle(aElement);
static NSUserInterfaceLayoutDirection DirectionForElement(
dom::Element* aElement) {
// Get the direction from the computed style so that inheritance into submenus
// is respected. aElement may not have a frame.
RefPtr<const ComputedStyle> sc =
nsComputedDOMStyle::GetComputedStyle(aElement);
if (!sc) {
return NSApp.userInterfaceLayoutDirection;
}
@ -711,11 +767,13 @@ void nsMenuX::RebuildMenu() {
}
if (menuPopup->IsElement()) {
mNativeMenu.userInterfaceLayoutDirection = DirectionForElement(menuPopup->AsElement());
mNativeMenu.userInterfaceLayoutDirection =
DirectionForElement(menuPopup->AsElement());
}
// Iterate over the kids
for (nsIContent* child = menuPopup->GetFirstChild(); child; child = child->GetNextSibling()) {
for (nsIContent* child = menuPopup->GetFirstChild(); child;
child = child->GetNextSibling()) {
if (Maybe<MenuChild> menuChild = CreateMenuChild(child)) {
AddMenuChild(std::move(*menuChild));
}
@ -732,9 +790,12 @@ void nsMenuX::InsertPlaceholderIfNeeded() {
if ([mNativeMenu numberOfItems] == 0) {
MOZ_RELEASE_ASSERT(mVisibleItemsCount == 0);
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@""
action:nil
keyEquivalent:@""];
item.enabled = NO;
item.view = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 150, 1)] autorelease];
item.view =
[[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 150, 1)] autorelease];
[mNativeMenu addItem:item];
[item release];
}
@ -800,11 +861,13 @@ GeckoNSMenu* nsMenuX::CreateMenuWithGeckoString(nsString& aMenuTitle) {
}
Maybe<nsMenuX::MenuChild> nsMenuX::CreateMenuChild(nsIContent* aContent) {
if (aContent->IsAnyOfXULElements(nsGkAtoms::menuitem, nsGkAtoms::menuseparator)) {
if (aContent->IsAnyOfXULElements(nsGkAtoms::menuitem,
nsGkAtoms::menuseparator)) {
return Some(MenuChild(CreateMenuItem(aContent)));
}
if (aContent->IsXULElement(nsGkAtoms::menu)) {
return Some(MenuChild(MakeRefPtr<nsMenuX>(this, mMenuGroupOwner, aContent)));
return Some(
MenuChild(MakeRefPtr<nsMenuX>(this, mMenuGroupOwner, aContent)));
}
return {};
}
@ -821,9 +884,10 @@ RefPtr<nsMenuItemX> nsMenuX::CreateMenuItem(nsIContent* aMenuItemContent) {
if (aMenuItemContent->IsXULElement(nsGkAtoms::menuseparator)) {
itemType = eSeparatorMenuItemType;
} else if (aMenuItemContent->IsElement()) {
static Element::AttrValuesArray strings[] = {nsGkAtoms::checkbox, nsGkAtoms::radio, nullptr};
switch (aMenuItemContent->AsElement()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
strings, eCaseMatters)) {
static Element::AttrValuesArray strings[] = {nsGkAtoms::checkbox,
nsGkAtoms::radio, nullptr};
switch (aMenuItemContent->AsElement()->FindAttrValueIn(
kNameSpaceID_None, nsGkAtoms::type, strings, eCaseMatters)) {
case 0:
itemType = eCheckboxMenuItemType;
break;
@ -833,17 +897,20 @@ RefPtr<nsMenuItemX> nsMenuX::CreateMenuItem(nsIContent* aMenuItemContent) {
}
}
return MakeRefPtr<nsMenuItemX>(this, menuitemName, itemType, mMenuGroupOwner, aMenuItemContent);
return MakeRefPtr<nsMenuItemX>(this, menuitemName, itemType, mMenuGroupOwner,
aMenuItemContent);
}
// This menu is about to open. Returns false if the handler wants to stop the opening of the menu.
// This menu is about to open. Returns false if the handler wants to stop the
// opening of the menu.
bool nsMenuX::OnOpen() {
if (mDidFirePopupshowingAndIsApprovedToOpen) {
return true;
}
if (mIsOpen) {
NS_WARNING("nsMenuX::OnOpen() called while the menu is already considered to be open. This "
NS_WARNING("nsMenuX::OnOpen() called while the menu is already considered "
"to be open. This "
"seems odd.");
}
@ -854,7 +921,8 @@ bool nsMenuX::OnOpen() {
}
nsEventStatus status = nsEventStatus_eIgnore;
WidgetMouseEvent event(true, eXULPopupShowing, nullptr, WidgetMouseEvent::eReal);
WidgetMouseEvent event(true, eXULPopupShowing, nullptr,
WidgetMouseEvent::eReal);
nsresult rv = NS_OK;
RefPtr<nsIContent> dispatchTo = popupContent ? popupContent : mContent;
@ -886,9 +954,9 @@ void nsMenuX::DidFirePopupShowing() {
}
}
// Find the |menupopup| child in the |popup| representing this menu. It should be one
// of a very few children so we won't be iterating over a bazillion menu items to find
// it (so the strcmp won't kill us).
// Find the |menupopup| child in the |popup| representing this menu. It should
// be one of a very few children so we won't be iterating over a bazillion menu
// items to find it (so the strcmp won't kill us).
already_AddRefed<nsIContent> nsMenuX::GetMenuPopupContent() {
// Check to see if we are a "menupopup" node (if we are a native menu).
if (mContent->IsXULElement(nsGkAtoms::menupopup)) {
@ -935,7 +1003,8 @@ bool nsMenuX::IsXULWindowMenu(nsIContent* aMenuContent) {
// nsChangeObserver
//
void nsMenuX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent* aContent,
void nsMenuX::ObserveAttributeChanged(dom::Document* aDocument,
nsIContent* aContent,
nsAtom* aAttribute) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -945,14 +1014,17 @@ void nsMenuX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent* aCon
}
if (aAttribute == nsGkAtoms::disabled) {
SetEnabled(!mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
nsGkAtoms::_true, eCaseMatters));
SetEnabled(!mContent->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true,
eCaseMatters));
} else if (aAttribute == nsGkAtoms::label) {
mContent->AsElement()->GetAttr(nsGkAtoms::label, mLabel);
NSString* newCocoaLabelString = nsMenuUtilsX::GetTruncatedCocoaLabel(mLabel);
NSString* newCocoaLabelString =
nsMenuUtilsX::GetTruncatedCocoaLabel(mLabel);
mNativeMenu.title = newCocoaLabelString;
mNativeMenuItem.title = newCocoaLabelString;
} else if (aAttribute == nsGkAtoms::hidden || aAttribute == nsGkAtoms::collapsed) {
} else if (aAttribute == nsGkAtoms::hidden ||
aAttribute == nsGkAtoms::collapsed) {
SetRebuild(true);
bool newVisible = !nsMenuUtilsX::NodeIsHiddenOrCollapsed(mContent);
@ -977,8 +1049,9 @@ void nsMenuX::ObserveAttributeChanged(dom::Document* aDocument, nsIContent* aCon
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void nsMenuX::ObserveContentRemoved(dom::Document* aDocument, nsIContent* aContainer,
nsIContent* aChild, nsIContent* aPreviousSibling) {
void nsMenuX::ObserveContentRemoved(dom::Document* aDocument,
nsIContent* aContainer, nsIContent* aChild,
nsIContent* aPreviousSibling) {
if (gConstructingMenu) {
return;
}
@ -991,7 +1064,8 @@ void nsMenuX::ObserveContentRemoved(dom::Document* aDocument, nsIContent* aConta
return;
}
// The menu is currently open. Remove the child from mMenuChildren and from our NSMenu.
// The menu is currently open. Remove the child from mMenuChildren and from
// our NSMenu.
nsCOMPtr<nsIContent> popupContent = GetMenuPopupContent();
if (popupContent && aContainer == popupContent && aChild->IsElement()) {
if (Maybe<MenuChild> child = GetItemForElement(aChild->AsElement())) {
@ -1000,7 +1074,8 @@ void nsMenuX::ObserveContentRemoved(dom::Document* aDocument, nsIContent* aConta
}
}
void nsMenuX::ObserveContentInserted(dom::Document* aDocument, nsIContent* aContainer,
void nsMenuX::ObserveContentInserted(dom::Document* aDocument,
nsIContent* aContainer,
nsIContent* aChild) {
if (gConstructingMenu) {
return;
@ -1013,7 +1088,8 @@ void nsMenuX::ObserveContentInserted(dom::Document* aDocument, nsIContent* aCont
return;
}
// The menu is currently open. Insert the child into mMenuChildren and into our NSMenu.
// The menu is currently open. Insert the child into mMenuChildren and into
// our NSMenu.
nsCOMPtr<nsIContent> popupContent = GetMenuPopupContent();
if (popupContent && aContainer == popupContent) {
if (Maybe<MenuChild> child = CreateMenuChild(aChild)) {
@ -1034,22 +1110,27 @@ void nsMenuX::IconUpdated() {
}
}
void nsMenuX::MenuChildChangedVisibility(const MenuChild& aChild, bool aIsVisible) {
void nsMenuX::MenuChildChangedVisibility(const MenuChild& aChild,
bool aIsVisible) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSMenuItem* nativeItem = aChild.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->NativeNSMenuItem(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->NativeNSMenuItem(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->NativeNSMenuItem();
});
if (aIsVisible) {
MOZ_RELEASE_ASSERT(!nativeItem.menu,
"The native item should not be in a menu while it is hidden");
MOZ_RELEASE_ASSERT(
!nativeItem.menu,
"The native item should not be in a menu while it is hidden");
RemovePlaceholderIfPresent();
NSInteger insertionPoint = CalculateNativeInsertionPoint(aChild);
[mNativeMenu insertItem:nativeItem atIndex:insertionPoint];
mVisibleItemsCount++;
} else {
MOZ_RELEASE_ASSERT([mNativeMenu indexOfItem:nativeItem] != -1,
"The native item should be in this menu while it is visible");
MOZ_RELEASE_ASSERT(
[mNativeMenu indexOfItem:nativeItem] != -1,
"The native item should be in this menu while it is visible");
[mNativeMenu removeItem:nativeItem];
mVisibleItemsCount--;
InsertPlaceholderIfNeeded();
@ -1067,7 +1148,9 @@ NSInteger nsMenuX::CalculateNativeInsertionPoint(const MenuChild& aChild) {
}
NSMenuItem* nativeItem = currItem.match(
[](const RefPtr<nsMenuX>& aMenu) { return aMenu->NativeNSMenuItem(); },
[](const RefPtr<nsMenuItemX>& aMenuItem) { return aMenuItem->NativeNSMenuItem(); });
[](const RefPtr<nsMenuItemX>& aMenuItem) {
return aMenuItem->NativeNSMenuItem();
});
// Only count visible items.
if (nativeItem.menu) {
insertionPoint++;
@ -1077,9 +1160,10 @@ NSInteger nsMenuX::CalculateNativeInsertionPoint(const MenuChild& aChild) {
}
void nsMenuX::Dump(uint32_t aIndent) const {
printf("%*s - menu [%p] %-16s <%s>", aIndent * 2, "", this,
mLabel.IsEmpty() ? "(empty label)" : NS_ConvertUTF16toUTF8(mLabel).get(),
NS_ConvertUTF16toUTF8(mContent->NodeName()).get());
printf(
"%*s - menu [%p] %-16s <%s>", aIndent * 2, "", this,
mLabel.IsEmpty() ? "(empty label)" : NS_ConvertUTF16toUTF8(mLabel).get(),
NS_ConvertUTF16toUTF8(mContent->NodeName()).get());
if (mNeedsRebuild) {
printf(" [NeedsRebuild]");
}
@ -1095,8 +1179,11 @@ void nsMenuX::Dump(uint32_t aIndent) const {
printf(" (%d visible items)", int(mVisibleItemsCount));
printf("\n");
for (const auto& subitem : mMenuChildren) {
subitem.match([=](const RefPtr<nsMenuX>& aMenu) { aMenu->Dump(aIndent + 1); },
[=](const RefPtr<nsMenuItemX>& aMenuItem) { aMenuItem->Dump(aIndent + 1); });
subitem.match(
[=](const RefPtr<nsMenuX>& aMenu) { aMenu->Dump(aIndent + 1); },
[=](const RefPtr<nsMenuItemX>& aMenuItem) {
aMenuItem->Dump(aIndent + 1);
});
}
}
@ -1108,8 +1195,8 @@ void nsMenuX::Dump(uint32_t aIndent) const {
- (id)initWithGeckoMenu:(nsMenuX*)geckoMenu {
if ((self = [super init])) {
NS_ASSERTION(geckoMenu,
"Cannot initialize native menu delegate with NULL gecko menu! Will crash!");
NS_ASSERTION(geckoMenu, "Cannot initialize native menu delegate with NULL "
"gecko menu! Will crash!");
mGeckoMenu = geckoMenu;
mBlocksToRunWhenOpen = [[NSMutableArray alloc] init];
}
@ -1131,7 +1218,8 @@ void nsMenuX::Dump(uint32_t aIndent) const {
}
Maybe<uint32_t> index =
aItem ? Some(static_cast<uint32_t>([aMenu indexOfItem:aItem])) : Nothing();
aItem ? Some(static_cast<uint32_t>([aMenu indexOfItem:aItem]))
: Nothing();
mGeckoMenu->OnHighlightedItemChanged(index);
}
@ -1269,7 +1357,8 @@ static NSMutableDictionary* gShadowKeyEquivDB = nil;
- (int)removeTable:(NSMapTable*)aTable {
if (aTable) {
NSValue* objectToRemove = [mTables member:[NSValue valueWithPointer:aTable]];
NSValue* objectToRemove =
[mTables member:[NSValue valueWithPointer:aTable]];
if (objectToRemove) {
[mTables removeObject:objectToRemove];
}
@ -1281,7 +1370,8 @@ static NSMutableDictionary* gShadowKeyEquivDB = nil;
@interface NSMenu (MethodSwizzling)
+ (void)nsMenuX_NSMenu_addItem:(NSMenuItem*)aItem toTable:(NSMapTable*)aTable;
+ (void)nsMenuX_NSMenu_removeItem:(NSMenuItem*)aItem fromTable:(NSMapTable*)aTable;
+ (void)nsMenuX_NSMenu_removeItem:(NSMenuItem*)aItem
fromTable:(NSMapTable*)aTable;
@end
@implementation NSMenu (MethodSwizzling)
@ -1304,7 +1394,8 @@ static NSMutableDictionary* gShadowKeyEquivDB = nil;
[self nsMenuX_NSMenu_addItem:aItem toTable:aTable];
}
+ (void)nsMenuX_NSMenu_removeItem:(NSMenuItem*)aItem fromTable:(NSMapTable*)aTable {
+ (void)nsMenuX_NSMenu_removeItem:(NSMenuItem*)aItem
fromTable:(NSMapTable*)aTable {
[self nsMenuX_NSMenu_removeItem:aItem fromTable:aTable];
if (aItem && aTable) {
@ -1382,7 +1473,9 @@ static NSMutableDictionary* gShadowKeyEquivDB = nil;
}
}
[self nsMenuX_populateMenu:aMenu withServiceEntries:filteredServices forDisplay:aForDisplay];
[self nsMenuX_populateMenu:aMenu
withServiceEntries:filteredServices
forDisplay:aForDisplay];
}
@end

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -73,7 +73,8 @@ NS_IMETHODIMP
nsPrintDialogServiceX::Init() { return NS_OK; }
NS_IMETHODIMP
nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSelection,
nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent,
bool aHaveSelection,
nsIPrintSettings* aSettings) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@ -84,7 +85,8 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
return NS_ERROR_FAILURE;
}
NSPrintInfo* printInfo = settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
NSPrintInfo* printInfo =
settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
if (NS_WARN_IF(!printInfo)) {
return NS_ERROR_FAILURE;
}
@ -100,7 +102,8 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
NULL, reinterpret_cast<const UniChar*>(adjustedTitle.BeginReading()),
adjustedTitle.Length());
if (cfTitleString) {
auto pmPrintSettings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
auto pmPrintSettings =
static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
::PMPrintSettingsSetJobName(pmPrintSettings, cfTitleString);
[printInfo updateFromPMPrintSettings];
CFRelease(cfTitleString);
@ -117,8 +120,8 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
// [panel runModal] will look for it. We create the view because otherwise
// we'll get unrelated warnings printed to the console.
NSView* tmpView = [[NSView alloc] init];
NSPrintOperation* printOperation = [NSPrintOperation printOperationWithView:tmpView
printInfo:printInfo];
NSPrintOperation* printOperation =
[NSPrintOperation printOperationWithView:tmpView printInfo:printInfo];
[NSPrintOperation setCurrentOperation:printOperation];
NSPrintPanel* panel = [NSPrintPanel printPanel];
@ -136,8 +139,9 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
int button = [panel runModal];
nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
// Retrieve a printInfo with the updated settings. (The NSPrintOperation operates on a
// copy, so the object we passed in will not have been modified.)
// Retrieve a printInfo with the updated settings. (The NSPrintOperation
// operates on a copy, so the object we passed in will not have been
// modified.)
NSPrintInfo* result = [[NSPrintOperation currentOperation] printInfo];
if (!result) {
return NS_ERROR_FAILURE;
@ -164,9 +168,9 @@ nsPrintDialogServiceX::ShowPrintDialog(mozIDOMWindowProxy* aParent, bool aHaveSe
[viewController exportSettings];
// Update our settings object based on the user's choices in the dialog.
// We tell settingsX to adopt this printInfo so that it will be used to run print job,
// so that any printer-specific custom settings from print dialog extension panels
// will be carried through.
// We tell settingsX to adopt this printInfo so that it will be used to run
// print job, so that any printer-specific custom settings from print dialog
// extension panels will be carried through.
settingsX->SetFromPrintInfo(result, /* aAdoptPrintInfo = */ true);
return NS_OK;
@ -188,7 +192,8 @@ nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
return NS_ERROR_FAILURE;
}
NSPrintInfo* printInfo = settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
NSPrintInfo* printInfo =
settingsX->CreateOrCopyPrintInfo(/* aWithScaling = */ true);
if (NS_WARN_IF(!printInfo)) {
return NS_ERROR_FAILURE;
}
@ -200,15 +205,17 @@ nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
if (button == NSFileHandlingPanelOKButton) {
// The Page Setup dialog does not include non-standard settings that need to be preserved,
// separate from what the base printSettings object handles, so we do not need it to adopt
// the printInfo object here.
// The Page Setup dialog does not include non-standard settings that need to
// be preserved, separate from what the base printSettings object handles,
// so we do not need it to adopt the printInfo object here.
settingsX->SetFromPrintInfo(printInfo, /* aAdoptPrintInfo = */ false);
nsCOMPtr<nsIPrintSettingsService> printSettingsService =
do_GetService("@mozilla.org/gfx/printsettings-service;1");
if (printSettingsService && Preferences::GetBool("print.save_print_settings", false)) {
if (printSettingsService &&
Preferences::GetBool("print.save_print_settings", false)) {
uint32_t flags = nsIPrintSettings::kInitSavePaperSize |
nsIPrintSettings::kInitSaveOrientation | nsIPrintSettings::kInitSaveScaling;
nsIPrintSettings::kInitSaveOrientation |
nsIPrintSettings::kInitSaveScaling;
printSettingsService->MaybeSavePrintSettingsToPrefs(aNSSettings, flags);
}
return NS_OK;
@ -234,7 +241,9 @@ nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
withFrame:(NSRect)aRect
alignment:(NSTextAlignment)aAlignment;
- (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect alignment:(NSTextAlignment)aAlignment;
- (void)addLabel:(const char*)aLabel
withFrame:(NSRect)aRect
alignment:(NSTextAlignment)aAlignment;
- (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect;
@ -243,7 +252,8 @@ nsPrintDialogServiceX::ShowPageSetupDialog(mozIDOMWindowProxy* aParent,
- (NSButton*)checkboxWithLabel:(const char*)aLabel andFrame:(NSRect)aRect;
- (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
selectedItem:(const nsAString&)aCurrentString;
selectedItem:
(const nsAString&)aCurrentString;
- (void)addOptionsSection:(bool)aHaveSelection;
@ -265,7 +275,8 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
// Public methods
- (id)initWithSettings:(nsIPrintSettings*)aSettings haveSelection:(bool)aHaveSelection {
- (id)initWithSettings:(nsIPrintSettings*)aSettings
haveSelection:(bool)aHaveSelection {
[super initWithFrame:NSMakeRect(0, 0, 540, 185)];
mSettings = aSettings;
@ -278,7 +289,8 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
}
- (void)exportSettings {
mSettings->SetPrintSelectionOnly([mPrintSelectionOnlyCheckbox state] == NSOnState);
mSettings->SetPrintSelectionOnly([mPrintSelectionOnlyCheckbox state] ==
NSOnState);
mSettings->SetShrinkToFit([mShrinkToFitCheckbox state] == NSOnState);
mSettings->SetPrintBGColors([mPrintBGColorsCheckbox state] == NSOnState);
mSettings->SetPrintBGImages([mPrintBGImagesCheckbox state] == NSOnState);
@ -294,8 +306,10 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
// Localization
- (void)initBundle {
nsCOMPtr<nsIStringBundleService> bundleSvc = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties", &mPrintBundle);
nsCOMPtr<nsIStringBundleService> bundleSvc =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties",
&mPrintBundle);
}
- (NSString*)localizedString:(const char*)aKey {
@ -303,11 +317,14 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
nsAutoString intlString;
mPrintBundle->GetStringFromName(aKey, intlString);
NSMutableString* s =
[NSMutableString stringWithUTF8String:NS_ConvertUTF16toUTF8(intlString).get()];
NSMutableString* s = [NSMutableString
stringWithUTF8String:NS_ConvertUTF16toUTF8(intlString).get()];
// Remove all underscores (they're used in the GTK dialog for accesskeys).
[s replaceOccurrencesOfString:@"_" withString:@"" options:0 range:NSMakeRange(0, [s length])];
[s replaceOccurrencesOfString:@"_"
withString:@""
options:0
range:NSMakeRange(0, [s length])];
return s;
}
@ -328,7 +345,9 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
return label;
}
- (void)addLabel:(const char*)aLabel withFrame:(NSRect)aRect alignment:(NSTextAlignment)aAlignment {
- (void)addLabel:(const char*)aLabel
withFrame:(NSRect)aRect
alignment:(NSTextAlignment)aAlignment {
NSTextField* label = [self label:aLabel withFrame:aRect alignment:aAlignment];
[self addSubview:label];
}
@ -352,16 +371,19 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
}
- (NSPopUpButton*)headerFooterItemListWithFrame:(NSRect)aRect
selectedItem:(const nsAString&)aCurrentString {
NSPopUpButton* list = [[[NSPopUpButton alloc] initWithFrame:aRect pullsDown:NO] autorelease];
selectedItem:
(const nsAString&)aCurrentString {
NSPopUpButton* list = [[[NSPopUpButton alloc] initWithFrame:aRect
pullsDown:NO] autorelease];
[list setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[[list cell] setControlSize:NSControlSizeSmall];
NSArray* items = [NSArray arrayWithObjects:[self localizedString:"headerFooterBlank"],
[self localizedString:"headerFooterTitle"],
[self localizedString:"headerFooterURL"],
[self localizedString:"headerFooterDate"],
[self localizedString:"headerFooterPage"],
[self localizedString:"headerFooterPageTotal"], nil];
NSArray* items = [NSArray
arrayWithObjects:[self localizedString:"headerFooterBlank"],
[self localizedString:"headerFooterTitle"],
[self localizedString:"headerFooterURL"],
[self localizedString:"headerFooterDate"],
[self localizedString:"headerFooterPage"],
[self localizedString:"headerFooterPageTotal"], nil];
[list addItemsWithTitles:items];
NS_ConvertUTF16toUTF8 currentStringUTF8(aCurrentString);
@ -382,8 +404,9 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
[self addLabel:"optionsTitleMac" withFrame:NSMakeRect(0, 155, 151, 22)];
// "Print Selection Only"
mPrintSelectionOnlyCheckbox = [self checkboxWithLabel:"selectionOnly"
andFrame:NSMakeRect(156, 155, 0, 0)];
mPrintSelectionOnlyCheckbox =
[self checkboxWithLabel:"selectionOnly"
andFrame:NSMakeRect(156, 155, 0, 0)];
[mPrintSelectionOnlyCheckbox setEnabled:aHaveSelection];
if (mSettings->GetPrintSelectionOnly()) {
@ -393,7 +416,8 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
[self addSubview:mPrintSelectionOnlyCheckbox];
// "Shrink To Fit"
mShrinkToFitCheckbox = [self checkboxWithLabel:"shrinkToFit" andFrame:NSMakeRect(156, 133, 0, 0)];
mShrinkToFitCheckbox = [self checkboxWithLabel:"shrinkToFit"
andFrame:NSMakeRect(156, 133, 0, 0)];
bool shrinkToFit;
mSettings->GetShrinkToFit(&shrinkToFit);
@ -437,33 +461,39 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
nsString sel;
mSettings->GetHeaderStrLeft(sel);
mHeaderLeftList = [self headerFooterItemListWithFrame:NSMakeRect(156, 44, 100, 22)
selectedItem:sel];
mHeaderLeftList =
[self headerFooterItemListWithFrame:NSMakeRect(156, 44, 100, 22)
selectedItem:sel];
[self addSubview:mHeaderLeftList];
mSettings->GetHeaderStrCenter(sel);
mHeaderCenterList = [self headerFooterItemListWithFrame:NSMakeRect(256, 44, 100, 22)
selectedItem:sel];
mHeaderCenterList =
[self headerFooterItemListWithFrame:NSMakeRect(256, 44, 100, 22)
selectedItem:sel];
[self addSubview:mHeaderCenterList];
mSettings->GetHeaderStrRight(sel);
mHeaderRightList = [self headerFooterItemListWithFrame:NSMakeRect(356, 44, 100, 22)
selectedItem:sel];
mHeaderRightList =
[self headerFooterItemListWithFrame:NSMakeRect(356, 44, 100, 22)
selectedItem:sel];
[self addSubview:mHeaderRightList];
mSettings->GetFooterStrLeft(sel);
mFooterLeftList = [self headerFooterItemListWithFrame:NSMakeRect(156, 0, 100, 22)
selectedItem:sel];
mFooterLeftList =
[self headerFooterItemListWithFrame:NSMakeRect(156, 0, 100, 22)
selectedItem:sel];
[self addSubview:mFooterLeftList];
mSettings->GetFooterStrCenter(sel);
mFooterCenterList = [self headerFooterItemListWithFrame:NSMakeRect(256, 0, 100, 22)
selectedItem:sel];
mFooterCenterList =
[self headerFooterItemListWithFrame:NSMakeRect(256, 0, 100, 22)
selectedItem:sel];
[self addSubview:mFooterCenterList];
mSettings->GetFooterStrRight(sel);
mFooterRightList = [self headerFooterItemListWithFrame:NSMakeRect(356, 0, 100, 22)
selectedItem:sel];
mFooterRightList =
[self headerFooterItemListWithFrame:NSMakeRect(356, 0, 100, 22)
selectedItem:sel];
[self addSubview:mFooterRightList];
}
@ -502,8 +532,9 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
- (NSString*)summaryValueForCheckbox:(NSButton*)aCheckbox {
if (![aCheckbox isEnabled]) return [self localizedString:"summaryNAValue"];
return [aCheckbox state] == NSOnState ? [self localizedString:"summaryOnValue"]
: [self localizedString:"summaryOffValue"];
return [aCheckbox state] == NSOnState
? [self localizedString:"summaryOnValue"]
: [self localizedString:"summaryOffValue"];
}
- (NSString*)headerSummaryValue {
@ -513,7 +544,8 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
stringByAppendingString:
[[mHeaderCenterList titleOfSelectedItem]
stringByAppendingString:
[@", " stringByAppendingString:[mHeaderRightList titleOfSelectedItem]]]]];
[@", " stringByAppendingString:
[mHeaderRightList titleOfSelectedItem]]]]];
}
- (NSString*)footerSummaryValue {
@ -523,43 +555,49 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
stringByAppendingString:
[[mFooterCenterList titleOfSelectedItem]
stringByAppendingString:
[@", " stringByAppendingString:[mFooterRightList titleOfSelectedItem]]]]];
[@", " stringByAppendingString:
[mFooterRightList titleOfSelectedItem]]]]];
}
- (NSArray*)localizedSummaryItems {
return [NSArray
arrayWithObjects:
[NSDictionary
dictionaryWithObjectsAndKeys:[self localizedString:"summarySelectionOnlyTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self
summaryValueForCheckbox:mPrintSelectionOnlyCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
dictionaryWithObjectsAndKeys:
[self localizedString:"summarySelectionOnlyTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mPrintSelectionOnlyCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[self localizedString:"summaryShrinkToFitTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mShrinkToFitCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey,
nil],
[NSDictionary
dictionaryWithObjectsAndKeys:[self localizedString:"summaryShrinkToFitTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mShrinkToFitCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
dictionaryWithObjectsAndKeys:
[self localizedString:"summaryPrintBGColorsTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mPrintBGColorsCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
[NSDictionary
dictionaryWithObjectsAndKeys:[self localizedString:"summaryPrintBGColorsTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mPrintBGColorsCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
[NSDictionary
dictionaryWithObjectsAndKeys:[self localizedString:"summaryPrintBGImagesTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mPrintBGImagesCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:[self localizedString:"summaryHeaderTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self headerSummaryValue],
NSPrintPanelAccessorySummaryItemDescriptionKey,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:[self localizedString:"summaryFooterTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self footerSummaryValue],
NSPrintPanelAccessorySummaryItemDescriptionKey,
nil],
dictionaryWithObjectsAndKeys:
[self localizedString:"summaryPrintBGImagesTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self summaryValueForCheckbox:mPrintBGImagesCheckbox],
NSPrintPanelAccessorySummaryItemDescriptionKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[self localizedString:"summaryHeaderTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self headerSummaryValue],
NSPrintPanelAccessorySummaryItemDescriptionKey,
nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[self localizedString:"summaryFooterTitle"],
NSPrintPanelAccessorySummaryItemNameKey,
[self footerSummaryValue],
NSPrintPanelAccessorySummaryItemDescriptionKey,
nil],
nil];
}
@ -569,11 +607,13 @@ static const char sHeaderFooterTags[][4] = {"", "&T", "&U", "&D", "&P", "&PT"};
@implementation PrintPanelAccessoryController
- (id)initWithSettings:(nsIPrintSettings*)aSettings haveSelection:(bool)aHaveSelection {
- (id)initWithSettings:(nsIPrintSettings*)aSettings
haveSelection:(bool)aHaveSelection {
[super initWithNibName:nil bundle:nil];
NSView* accView = [[PrintPanelAccessoryView alloc] initWithSettings:aSettings
haveSelection:aHaveSelection];
NSView* accView =
[[PrintPanelAccessoryView alloc] initWithSettings:aSettings
haveSelection:aHaveSelection];
[self setView:accView];
[accView release];
return self;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше