Bug 1629313 - Part 1 - Set As Desktop Background fails on macOS r=spohl
Change the nsMacShellService::SetDesktopBackground() implementation (specifically code in the OnStateChange handler) to use the Apple setDesktopImageURL API instead of Apple Events to allow the "Set As Desktop Background..." context menu option to work again. Alternatively, to allow the AppleEvent-base implementation to work again, Firefox could be signed with the com.apple.security.automation.apple-events entitlement but this would also require the user to grant Firefox permission to control Finder. setDesktopImageURL requires Mac OS 10.6 or newer and hence was not an option originally. The implementation only changes the background of the focused screen in the current workspace (which matches the behavior of Safari). Differential Revision: https://phabricator.services.mozilla.com/D71426
This commit is contained in:
@@ -18,12 +18,14 @@
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "DesktopBackgroundImage.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
using mozilla::dom::Element;
|
||||
using mozilla::widget::SetDesktopImage;
|
||||
|
||||
#define NETWORK_PREFPANE \
|
||||
NS_LITERAL_CSTRING("/System/Library/PreferencePanes/Network.prefPane")
|
||||
@@ -206,57 +208,12 @@ nsMacShellService::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
os->NotifyObservers(nullptr, "shell:desktop-background-changed", nullptr);
|
||||
|
||||
bool exists = false;
|
||||
mBackgroundFile->Exists(&exists);
|
||||
if (!exists) return NS_OK;
|
||||
|
||||
nsAutoCString nativePath;
|
||||
mBackgroundFile->GetNativePath(nativePath);
|
||||
|
||||
AEDesc tAEDesc = {typeNull, nil};
|
||||
OSErr err = noErr;
|
||||
AliasHandle aliasHandle = nil;
|
||||
FSRef pictureRef;
|
||||
OSStatus status;
|
||||
|
||||
// Convert the path into a FSRef
|
||||
status =
|
||||
::FSPathMakeRef((const UInt8*)nativePath.get(), &pictureRef, nullptr);
|
||||
if (status == noErr) {
|
||||
err = ::FSNewAlias(nil, &pictureRef, &aliasHandle);
|
||||
if (err == noErr && aliasHandle == nil) err = paramErr;
|
||||
|
||||
if (err == noErr) {
|
||||
// We need the descriptor (based on the picture file reference)
|
||||
// for the 'Set Desktop Picture' apple event.
|
||||
char handleState = ::HGetState((Handle)aliasHandle);
|
||||
::HLock((Handle)aliasHandle);
|
||||
err = ::AECreateDesc(typeAlias, *aliasHandle,
|
||||
GetHandleSize((Handle)aliasHandle), &tAEDesc);
|
||||
// unlock the alias handler
|
||||
::HSetState((Handle)aliasHandle, handleState);
|
||||
::DisposeHandle((Handle)aliasHandle);
|
||||
}
|
||||
if (err == noErr) {
|
||||
AppleEvent tAppleEvent;
|
||||
OSType sig = 'MACS';
|
||||
AEBuildError tAEBuildError;
|
||||
// Create a 'Set Desktop Pictue' Apple Event
|
||||
err =
|
||||
::AEBuildAppleEvent(kAECoreSuite, kAESetData, typeApplSignature,
|
||||
&sig, sizeof(OSType), kAutoGenerateReturnID,
|
||||
kAnyTransactionID, &tAppleEvent, &tAEBuildError,
|
||||
"'----':'obj '{want:type (prop),form:prop"
|
||||
",seld:type('dpic'),from:'null'()},data:(@)",
|
||||
&tAEDesc);
|
||||
if (err == noErr) {
|
||||
AppleEvent reply = {typeNull, nil};
|
||||
// Sent the event we built, the reply event isn't necessary
|
||||
err = ::AESend(&tAppleEvent, &reply, kAENoReply, kAENormalPriority,
|
||||
kNoTimeOut, nil, nil);
|
||||
::AEDisposeDesc(&tAppleEvent);
|
||||
}
|
||||
}
|
||||
nsresult rv = mBackgroundFile->Exists(&exists);
|
||||
if (NS_FAILED(rv) || !exists) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SetDesktopImage(mBackgroundFile);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
Reference in New Issue
Block a user