mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 09:58:03 +02:00
Wallpaper (macOS): extracts image path from NSData Configuration field
Also moves NSWorkspace method to the last method to try Fixes #2559
This commit is contained in:
@@ -5,79 +5,125 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
const char* ffDetectWallpaper(FFstrbuf* result)
|
||||
{
|
||||
{
|
||||
// Reliable for user-picked static images.
|
||||
NSURL* url = [NSWorkspace.sharedWorkspace desktopImageURLForScreen:NSScreen.mainScreen];
|
||||
if (url.fileURL && ![url.path isEqualToString:@"/System/Library/CoreServices/DefaultDesktop.heic"] /* dynamic wallpapers */)
|
||||
{
|
||||
ffStrbufSetS(result, url.path.UTF8String);
|
||||
return nullptr;
|
||||
}
|
||||
const char* detectFromPlist(FFstrbuf* result) {
|
||||
// For Sonoma and later (macOS 14.0+)
|
||||
// https://github.com/JohnCoates/Aerial/issues/1332
|
||||
NSError* error;
|
||||
NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Application Support/com.apple.wallpaper/Store/Index.plist", instance.state.platform.homeDir.chars];
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
|
||||
if (error) {
|
||||
return "Failed to read wallpaper plist file";
|
||||
}
|
||||
|
||||
{
|
||||
// For Sonoma
|
||||
// https://github.com/JohnCoates/Aerial/issues/1332
|
||||
NSError* error;
|
||||
NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Application Support/com.apple.wallpaper/Store/Index.plist", instance.state.platform.homeDir.chars];
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
if (!error)
|
||||
{
|
||||
NSArray* choices = [dict valueForKeyPath:@"SystemDefault.Desktop.Content.Choices"];
|
||||
if (choices.count > 0)
|
||||
{
|
||||
NSDictionary* choice = choices[0];
|
||||
NSArray* files = choice[@"Files"];
|
||||
if (files.count > 0)
|
||||
{
|
||||
NSString* file = files[0][@"relative"];
|
||||
ffStrbufAppendS(result, [NSURL URLWithString:file].path.UTF8String);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString* provider = choice[@"Provider"];
|
||||
NSString* builtinPrefix = @"com.apple.wallpaper.choice.";
|
||||
if ([provider hasPrefix:builtinPrefix])
|
||||
provider = [provider substringFromIndex:builtinPrefix.length];
|
||||
if ([provider isEqualToString:@"sonoma"])
|
||||
ffStrbufSetStatic(result, "macOS Sonoma");
|
||||
else if ([provider isEqualToString:@"aerials"]) // Most builtin aerial wallpapers are private
|
||||
ffStrbufSetStatic(result, "Built-in aerial photography");
|
||||
else
|
||||
ffStrbufAppendF(result, "Built-in %s wallpaper", provider.UTF8String);
|
||||
NSArray* choices = [dict valueForKeyPath:@"SystemDefault.Desktop.Content.Choices"];
|
||||
if (choices.count > 0) {
|
||||
NSDictionary* choice = choices[0];
|
||||
|
||||
NSArray* files = choice[@"Files"];
|
||||
if (files.count > 0) {
|
||||
NSString* file = files[0][@"relative"];
|
||||
ffStrbufSetS(result, [NSURL URLWithString:file].path.UTF8String);
|
||||
}
|
||||
|
||||
if (result->length == 0) {
|
||||
NSData* configData = choice[@"Configuration"];
|
||||
if (configData && configData.length > 0) {
|
||||
NSError* plistError = nil;
|
||||
NSDictionary* configPlist = [NSPropertyListSerialization propertyListWithData:configData
|
||||
options:NSPropertyListImmutable
|
||||
format:NULL
|
||||
error:&plistError];
|
||||
|
||||
if (!plistError && [configPlist isKindOfClass:NSDictionary.class]) {
|
||||
NSDictionary* urlDict = configPlist[@"url"];
|
||||
if ([urlDict isKindOfClass:NSDictionary.class]) {
|
||||
NSString* relativeUrlString = urlDict[@"relative"];
|
||||
if ([relativeUrlString isKindOfClass:[NSString class]]) {
|
||||
NSURL* fileUrl = [NSURL URLWithString:relativeUrlString];
|
||||
if (fileUrl.fileURL) {
|
||||
ffStrbufSetS(result, fileUrl.path.UTF8String);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result->length == 0) {
|
||||
NSString* provider = choice[@"Provider"];
|
||||
if ([provider isKindOfClass:NSString.class]) {
|
||||
NSString* builtinPrefix = @"com.apple.wallpaper.choice.";
|
||||
if ([provider hasPrefix:builtinPrefix]) {
|
||||
provider = [provider substringFromIndex:builtinPrefix.length];
|
||||
}
|
||||
|
||||
// macOS internal wallpapers
|
||||
if ([provider isEqualToString:@"aerials"]) { // Most builtin aerial wallpapers are private
|
||||
ffStrbufSetStatic(result, "Built-in aerial photography");
|
||||
} else if ([provider isEqualToString:@"default"]) {
|
||||
ffStrbufSetStatic(result, "macOS Default Wallpaper");
|
||||
} else {
|
||||
ffStrbufSetF(result, "Built-in %s wallpaper", provider.UTF8String);
|
||||
}
|
||||
}
|
||||
if (result->length > 0)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (result->length == 0) {
|
||||
return "Failed to detect wallpaper from plist";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
|
||||
{
|
||||
// For Ventura
|
||||
// https://stackoverflow.com/questions/301215/getting-desktop-background-on-mac
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&instance.state.platform.homeDir);
|
||||
ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db");
|
||||
if (ffSettingsGetSQLite3String(path.chars,
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
const char* detectFromSQLite(FFstrbuf* result) {
|
||||
// For Ventura
|
||||
// https://stackoverflow.com/questions/301215/getting-desktop-background-on-mac
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&instance.state.platform.homeDir);
|
||||
ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db");
|
||||
if (ffSettingsGetSQLite3String(path.chars,
|
||||
"SELECT value\n"
|
||||
"FROM preferences\n"
|
||||
"JOIN data ON preferences.data_id=data.ROWID\n"
|
||||
"JOIN pictures ON preferences.picture_id=pictures.ROWID\n"
|
||||
"JOIN displays ON pictures.display_id=displays.ROWID\n"
|
||||
"JOIN spaces ON pictures.space_id=spaces.ROWID\n"
|
||||
"WHERE display_id=1 AND space_id=1 AND key=1", result)
|
||||
)
|
||||
return nullptr;
|
||||
"WHERE display_id=1 AND space_id=1 AND key=1",
|
||||
result)) {
|
||||
return nullptr;
|
||||
}
|
||||
return "Failed to detect wallpaper from SQLite database";
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* detectFromNSWorkspace(FFstrbuf* result) {
|
||||
// Reliable for user-picked static images.
|
||||
NSScreen* mainScreen = NSScreen.mainScreen;
|
||||
if (!mainScreen) {
|
||||
return "Failed to detect wallpaper from NSWorkspace: No main screen found";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
|
||||
NSURL* url = [NSWorkspace.sharedWorkspace desktopImageURLForScreen:mainScreen];
|
||||
if (url.fileURL) {
|
||||
ffStrbufSetS(result, url.path.UTF8String);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return "All detection methods failed";
|
||||
return "Failed to detect wallpaper from NSWorkspace";
|
||||
}
|
||||
|
||||
const char* ffDetectWallpaper(FFstrbuf* result) {
|
||||
const char* error;
|
||||
|
||||
if (@available(macOS 14.0, *)) {
|
||||
error = detectFromPlist(result);
|
||||
} else {
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
error = detectFromSQLite(result);
|
||||
#else
|
||||
error = detectFromNSWorkspace(result);
|
||||
#endif
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user