summaryrefslogtreecommitdiffstats
path: root/src/detection/wallpaper
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/wallpaper
Add the files
Diffstat (limited to 'src/detection/wallpaper')
-rw-r--r--src/detection/wallpaper/wallpaper.h5
-rw-r--r--src/detection/wallpaper/wallpaper_apple.m72
-rw-r--r--src/detection/wallpaper/wallpaper_haiku.cpp54
-rw-r--r--src/detection/wallpaper/wallpaper_linux.c102
-rw-r--r--src/detection/wallpaper/wallpaper_nosupport.c5
-rw-r--r--src/detection/wallpaper/wallpaper_windows.c15
6 files changed, 253 insertions, 0 deletions
diff --git a/src/detection/wallpaper/wallpaper.h b/src/detection/wallpaper/wallpaper.h
new file mode 100644
index 0000000..96fead9
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "fastfetch.h"
+
+const char* ffDetectWallpaper(FFstrbuf* result);
diff --git a/src/detection/wallpaper/wallpaper_apple.m b/src/detection/wallpaper/wallpaper_apple.m
new file mode 100644
index 0000000..800aee9
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper_apple.m
@@ -0,0 +1,72 @@
+#include "wallpaper.h"
+#include "common/settings.h"
+#include "common/apple/osascript.h"
+
+#import <Foundation/Foundation.h>
+
+const char* ffDetectWallpaper(FFstrbuf* result)
+{
+ {
+ // 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);
+ }
+ }
+ if (result->length > 0)
+ return NULL;
+ }
+ }
+
+ #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,
+ "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 NULL;
+ }
+
+ #endif
+
+ if (ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
+ return NULL;
+
+ return "All detection methods failed";
+}
diff --git a/src/detection/wallpaper/wallpaper_haiku.cpp b/src/detection/wallpaper/wallpaper_haiku.cpp
new file mode 100644
index 0000000..0bfad62
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper_haiku.cpp
@@ -0,0 +1,54 @@
+extern "C" {
+#include "wallpaper.h"
+#include "common/mallocHelper.h"
+}
+
+#include <Application.h>
+#include <FindDirectory.h>
+#include <InterfaceDefs.h>
+#include <Node.h>
+#include <Path.h>
+#include <Screen.h>
+#include <fs_attr.h>
+#include <be_apps/Tracker/Background.h>
+
+const char* ffDetectWallpaper(FFstrbuf* result) {
+ BMessage backgrounds;
+ BPath pDesktop;
+ BString path;
+
+ if (find_directory(B_DESKTOP_DIRECTORY, &pDesktop) < B_OK) {
+ return "find_directory(B_DESKTOP_DIRECTORY) failed";
+ }
+
+ // We need a valid be_app to query the app_server here.
+ BApplication app("application/x-vnd.fastfetch-cli-fastfetch");
+
+ BNode nDesktop(pDesktop.Path());
+ if (nDesktop.InitCheck() == B_OK) {
+ struct attr_info ai;
+ if (nDesktop.GetAttrInfo(B_BACKGROUND_INFO, &ai) == B_OK && ai.size > 0) {
+ FF_AUTO_FREE char* pAttr = (char*) malloc(ai.size);
+ if (nDesktop.ReadAttr(B_BACKGROUND_INFO, ai.type, 0LL, pAttr, (size_t) ai.size) >= B_OK) {
+ if (backgrounds.Unflatten(pAttr) == B_OK) {
+ for (int i = 0; backgrounds.FindString(B_BACKGROUND_IMAGE, i, &path) == B_OK; i++) {
+ int32 ws;
+ if (backgrounds.FindInt32(B_BACKGROUND_WORKSPACES, i, &ws) == B_OK) {
+ if (ws & (1 << current_workspace())) {
+ // We try to match the one for the current workspace
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (path.Length() < 1) {
+ return "Failed to detect the current wallpaper path";
+ }
+
+ ffStrbufAppendS(result, path.String());
+ return NULL;
+}
diff --git a/src/detection/wallpaper/wallpaper_linux.c b/src/detection/wallpaper/wallpaper_linux.c
new file mode 100644
index 0000000..f5ad4ec
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper_linux.c
@@ -0,0 +1,102 @@
+#include "wallpaper.h"
+#include "common/io.h"
+#include "common/settings.h"
+#include "detection/displayserver/displayserver.h"
+#include "detection/gtk_qt/gtk_qt.h"
+
+static const char* detectCosmicComp(FFstrbuf* result) {
+ FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(FF_LIST_FIRST(FFstrbuf, instance.state.platform.configDirs));
+ ffStrbufAppendS(&path, "cosmic/com.system76.CosmicBackground/v1/");
+ uint32_t basePathLength = path.length;
+
+ FF_STRBUF_AUTO_DESTROY backgrounds = ffStrbufCreate();
+ ffStrbufAppendS(&path, "backgrounds");
+ bool sharedWallpaper = true;
+ FF_STRBUF_AUTO_DESTROY monitorName = ffStrbufCreate();
+ if (ffReadFileBuffer(path.chars, &backgrounds)) {
+ FF_STRBUF_AUTO_DESTROY cleaned = ffStrbufCreateCopy(&backgrounds);
+ ffStrbufRemoveStrings(&cleaned, 4, (const char*[]){ " ", "\n", "\r", "\t" });
+
+ if (!ffStrbufEqualS(&cleaned, "[]")) {
+ const char* firstQuote = strchr(backgrounds.chars, '"');
+ if (firstQuote != NULL) {
+ const char* secondQuote = strchr(firstQuote + 1, '"');
+ if (secondQuote != NULL && secondQuote > firstQuote + 1) {
+ ffStrbufAppendNS(&monitorName, (uint32_t) (secondQuote - firstQuote - 1), firstQuote + 1);
+ sharedWallpaper = false;
+ }
+ }
+ }
+ }
+ ffStrbufSubstrBefore(&path, basePathLength);
+
+ if (sharedWallpaper) {
+ ffStrbufAppendS(&path, "all");
+ } else {
+ ffStrbufAppendS(&path, "output.");
+ ffStrbufAppend(&path, &monitorName);
+ }
+
+ FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate();
+ if (!ffReadFileBuffer(path.chars, &output)) {
+ return "Failed to read COSMIC wallpaper config";
+ }
+
+ const char* sourceStart = strstr(output.chars, "source:");
+ if (sourceStart == NULL) {
+ return "COSMIC wallpaper config doesn't contain source";
+ }
+
+ const char* pathStart = strstr(sourceStart, "Path(");
+ if (pathStart == NULL) {
+ return "COSMIC wallpaper source is not a Path value";
+ }
+
+ pathStart += strlen("Path(");
+ while (*pathStart == ' ' || *pathStart == '\t') {
+ ++pathStart;
+ }
+
+ if (*pathStart != '\'' && *pathStart != '"') {
+ return "COSMIC wallpaper Path format is invalid";
+ }
+
+ char quote = *pathStart;
+ ++pathStart;
+ const char* pathEnd = strchr(pathStart, quote);
+ if (pathEnd == NULL || pathEnd == pathStart) {
+ return "COSMIC wallpaper path is empty";
+ }
+
+ ffStrbufAppendNS(result, (uint32_t) (pathEnd - pathStart), pathStart);
+ return NULL;
+}
+
+const char* ffDetectWallpaper(FFstrbuf* result) {
+ const FFDisplayServerResult* wm = ffConnectDisplayServer();
+ if (ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_COSMIC_COMP)) {
+ return detectCosmicComp(result);
+ }
+
+ const FFstrbuf* wallpaper = NULL;
+ const FFGTKResult* gtk = ffDetectGTK4();
+ if (gtk->wallpaper.length) {
+ wallpaper = &gtk->wallpaper;
+ } else {
+ const FFQtResult* qt = ffDetectQt();
+ if (qt->wallpaper.length) {
+ wallpaper = &qt->wallpaper;
+ }
+ }
+
+ if (!wallpaper) {
+ return "Failed to detect the current wallpaper path";
+ }
+
+ if (ffStrbufStartsWithS(wallpaper, "file:///")) {
+ ffStrbufAppendS(result, wallpaper->chars + strlen("file://"));
+ } else {
+ ffStrbufAppend(result, wallpaper);
+ }
+ return NULL;
+}
diff --git a/src/detection/wallpaper/wallpaper_nosupport.c b/src/detection/wallpaper/wallpaper_nosupport.c
new file mode 100644
index 0000000..9be8e91
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper_nosupport.c
@@ -0,0 +1,5 @@
+#include "wallpaper.h"
+
+const char* ffDetectWallpaper(FF_A_UNUSED FFstrbuf* result) {
+ return "Not supported on this platform";
+}
diff --git a/src/detection/wallpaper/wallpaper_windows.c b/src/detection/wallpaper/wallpaper_windows.c
new file mode 100644
index 0000000..2adf083
--- /dev/null
+++ b/src/detection/wallpaper/wallpaper_windows.c
@@ -0,0 +1,15 @@
+#include "wallpaper.h"
+#include "common/windows/registry.h"
+
+const char* ffDetectWallpaper(FFstrbuf* result) {
+ FF_AUTO_CLOSE_FD HANDLE hKey = NULL;
+ if (!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Desktop", &hKey, NULL)) {
+ return "ffRegOpenKeyForRead(Control Panel\\Desktop) failed";
+ }
+
+ if (!ffRegReadStrbuf(hKey, L"WallPaper", result, NULL)) {
+ return "ffRegReadStrbuf(WallPaper) failed";
+ }
+
+ return NULL;
+}