Skip to content

Commit cf713e3

Browse files
committed
Wallpaper (Linux): improves XFCE wallpaper detection via property enumeration
1 parent 7d08f81 commit cf713e3

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

src/common/settings.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,96 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
250250

251251
return FF_VARIANT_NULL;
252252
}
253+
254+
#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
255+
{ \
256+
if(!(dbus).lib->ffdbus_message_iter_next(iterator)) \
257+
break; \
258+
continue; \
259+
}
260+
261+
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
262+
{
263+
FFDBusData dbus;
264+
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL)
265+
return FF_VARIANT_NULL;
266+
267+
DBusMessage* reply = ffDBusGetMethodReply(&dbus, "org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "GetAllProperties", channelName, propertyPrefix);
268+
if(!reply)
269+
return FF_VARIANT_NULL;
270+
271+
DBusMessageIter rootIterator;
272+
if(!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator))
273+
{
274+
dbus.lib->ffdbus_message_unref(reply);
275+
return FF_VARIANT_NULL;
276+
}
277+
278+
DBusMessageIter arrayIterator;
279+
dbus.lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator);
280+
281+
while(true)
282+
{
283+
if(dbus.lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY)
284+
FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
285+
286+
DBusMessageIter dictIterator;
287+
dbus.lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator);
288+
289+
const char* key;
290+
dbus.lib->ffdbus_message_iter_get_basic(&dictIterator, &key);
291+
292+
if (cb(data, key)) FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
293+
dbus.lib->ffdbus_message_iter_next(&dictIterator);
294+
295+
if(type == FF_VARIANT_TYPE_INT)
296+
{
297+
int32_t value;
298+
if (ffDBusGetInt(&dbus, &dictIterator, &value))
299+
{
300+
dbus.lib->ffdbus_message_unref(reply);
301+
return (FFvariant) { .intValue = value };
302+
}
303+
return FF_VARIANT_NULL;
304+
}
305+
306+
if(type == FF_VARIANT_TYPE_STRING)
307+
{
308+
FFstrbuf value = ffStrbufCreate();
309+
if (ffDBusGetString(&dbus, &dictIterator, &value))
310+
{
311+
dbus.lib->ffdbus_message_unref(reply);
312+
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
313+
}
314+
return FF_VARIANT_NULL;
315+
}
316+
317+
if(type == FF_VARIANT_TYPE_BOOL)
318+
{
319+
bool value;
320+
if (ffDBusGetBool(&dbus, &dictIterator, &value))
321+
{
322+
dbus.lib->ffdbus_message_unref(reply);
323+
return (FFvariant) { .boolValue = value, .boolValueSet = true };
324+
}
325+
}
326+
327+
return FF_VARIANT_NULL;
328+
}
329+
330+
return FF_VARIANT_NULL;
331+
}
253332
#else //FF_HAVE_DBUS
254333
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
255334
{
256335
FF_UNUSED(channelName, propertyName, type)
257336
return FF_VARIANT_NULL;
258337
}
338+
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
339+
{
340+
FF_UNUSED(channelName, propertyPrefix, type, data, cb);
341+
return FF_VARIANT_NULL;
342+
}
259343
#endif //FF_HAVE_DBUS
260344

261345
#ifdef FF_HAVE_SQLITE3

src/common/settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type);
2626
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type);
2727
FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
2828
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type);
29+
typedef bool FFTestXfconfPropCallback(void* data, const char* propertyName); // Return false to break loop
30+
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb);
2931

3032
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query);
3133
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result);

src/detection/gtk_qt/gtk.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
3434
ffStrbufAppendS(&result->wallpaper, wallpaper);
3535
}
3636

37+
static bool testXfconfWallpaperPropKey(FF_MAYBE_UNUSED void* data, const char* key)
38+
{
39+
int count = 0;
40+
sscanf(key, "/backdrop/screen0/monitor%*[^/]/workspace0/last-image%n", &count);
41+
return count == 0;
42+
}
43+
3744
static void detectGTKFromSettings(FFGTKResult* result)
3845
{
3946
static const char* themeName = NULL;
@@ -62,11 +69,7 @@ static void detectGTKFromSettings(FFGTKResult* result)
6269
fontName = ffSettingsGetXFConf("xsettings", "/Gtk/FontName", FF_VARIANT_TYPE_STRING).strValue;
6370
cursorTheme = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue;
6471
cursorSize = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
65-
wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
66-
if (!wallpaper) // FIXME: find a way to enumerate possible properties
67-
wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitoreDP-1/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
68-
if (!wallpaper)
69-
wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitorbuiltin/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
72+
wallpaper = ffSettingsGetXFConfFirstMatch("xfce4-desktop", "/backdrop/screen0", FF_VARIANT_TYPE_STRING, NULL, testXfconfWallpaperPropKey).strValue;
7073
}
7174
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_CINNAMON) == 0)
7275
{

0 commit comments

Comments
 (0)