Fix XFCE wallpaper not applying (wrong monitor property + broken xfconf

array write)
This commit is contained in:
AnmiTaliDev 2026-08-20 09:11:05 +05:00
parent 02b6909e85
commit e318e5ed23
No known key found for this signature in database
GPG key ID: C15CE1C091FF3004

View file

@ -49,11 +49,15 @@
static bool hasPictureURIDark = false; static bool hasPictureURIDark = false;
// XFCE settings // XFCE settings
static XfconfChannel* bgchannel; static XfconfChannel* bgchannel;
static int defPictureStyle; static std::vector<std::string> xfceMonitorPrefixes;
static int defColorStyle; static std::map<std::string, std::string> defXfcePictureURI;
static GValue defColor = G_VALUE_INIT; static std::map<std::string, int> defXfcePictureStyle;
static bool defColorExists; static std::map<std::string, int> defXfceColorStyle;
static std::string optionImage, optionColor, optionImageStyle, optionColorStyle; static std::map<std::string, GValue> defXfceColor;
static std::map<std::string, bool> defXfceColorExists;
static bool xfceHasSingleWorkspaceProps = false;
static bool xfceSingleWorkspaceMode = false;
static int xfceSingleWorkspaceNumber = 0;
// KDE settings // KDE settings
static std::map<std::string, std::string> defPlugins, defPictures, defColors, defModes; static std::map<std::string, std::string> defPlugins, defPictures, defColors, defModes;
static std::map<std::string, bool> defBlurs; static std::map<std::string, bool> defBlurs;
@ -191,15 +195,55 @@
GError *xferror = NULL; GError *xferror = NULL;
if (xfconf_init(&xferror)) { if (xfconf_init(&xferror)) {
bgchannel = xfconf_channel_get("xfce4-desktop"); bgchannel = xfconf_channel_get("xfce4-desktop");
std::string optionPrefix = "/backdrop/screen0/monitor0/workspace0/";
optionImage = optionPrefix + "last-image"; GHashTable *props = xfconf_channel_get_properties(bgchannel, "/backdrop");
optionColor = optionPrefix + "color1"; if (props) {
optionImageStyle = optionPrefix + "image-style"; const std::string suffix = "/last-image";
optionColorStyle = optionPrefix + "color-style"; GHashTableIter iter;
defPictureURI = xfconf_channel_get_string(bgchannel, optionImage.c_str(), ""); gpointer key, value;
defPictureStyle = xfconf_channel_get_int(bgchannel, optionImageStyle.c_str(), -1); g_hash_table_iter_init(&iter, props);
defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor); while (g_hash_table_iter_next(&iter, &key, &value)) {
defColorStyle = xfconf_channel_get_int(bgchannel, optionColorStyle.c_str(), -1); std::string propPath((const char*)key);
if (propPath.size() > suffix.size() &&
propPath.compare(propPath.size() - suffix.size(), suffix.size(), suffix) == 0) {
xfceMonitorPrefixes.push_back(propPath.substr(0, propPath.size() - suffix.size() + 1));
}
}
g_hash_table_destroy(props);
}
if (xfceMonitorPrefixes.empty()) {
xfceMonitorPrefixes.push_back("/backdrop/screen0/monitor0/workspace0/");
}
xfceHasSingleWorkspaceProps = xfconf_channel_has_property(bgchannel, "/backdrop/single-workspace-mode");
if (xfceHasSingleWorkspaceProps) {
xfceSingleWorkspaceMode = xfconf_channel_get_bool(bgchannel, "/backdrop/single-workspace-mode", true);
xfceSingleWorkspaceNumber = xfconf_channel_get_int(bgchannel, "/backdrop/single-workspace-number", 0);
}
if (xfceHasSingleWorkspaceProps && xfceSingleWorkspaceMode) {
std::vector<std::string> extraPrefixes;
for (const std::string &prefix : xfceMonitorPrefixes) {
std::size_t workspacePos = prefix.rfind("/workspace");
if (workspacePos == std::string::npos)
continue;
std::string monitorBase = prefix.substr(0, workspacePos + 1);
std::string activePrefix = monitorBase + "workspace" + std::to_string(xfceSingleWorkspaceNumber) + "/";
if (std::find(xfceMonitorPrefixes.begin(), xfceMonitorPrefixes.end(), activePrefix) == xfceMonitorPrefixes.end() &&
std::find(extraPrefixes.begin(), extraPrefixes.end(), activePrefix) == extraPrefixes.end()) {
extraPrefixes.push_back(activePrefix);
}
}
xfceMonitorPrefixes.insert(xfceMonitorPrefixes.end(), extraPrefixes.begin(), extraPrefixes.end());
}
for (const std::string &prefix : xfceMonitorPrefixes) {
defXfcePictureURI[prefix] = xfconf_channel_get_string(bgchannel, (prefix + "last-image").c_str(), "");
defXfcePictureStyle[prefix] = xfconf_channel_get_int(bgchannel, (prefix + "image-style").c_str(), -1);
defXfceColorStyle[prefix] = xfconf_channel_get_int(bgchannel, (prefix + "color-style").c_str(), -1);
GValue colorVal = G_VALUE_INIT;
defXfceColorExists[prefix] = xfconf_channel_get_property(bgchannel, (prefix + "color1").c_str(), &colorVal);
defXfceColor[prefix] = colorVal;
}
} else { } else {
// Configuration failed to initialize, we won't set the wallpaper // Configuration failed to initialize, we won't set the wallpaper
printf("[desktopEnvironmentInit] Configuration failed to initialize, we won't set the wallpaper\n"); printf("[desktopEnvironmentInit] Configuration failed to initialize, we won't set the wallpaper\n");
@ -457,49 +501,47 @@ end:
unsigned int ub = b * 256 + b; unsigned int ub = b * 256 + b;
unsigned int alpha = 65535; unsigned int alpha = 65535;
std::string concatPath(gameDirStr + path); std::string concatPath(gameDirStr + path);
xfconf_channel_set_string(bgchannel, optionImage.c_str(), concatPath.c_str()); for (const std::string &prefix : xfceMonitorPrefixes) {
xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), 0); std::string optionImage = prefix + "last-image";
xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), 4); std::string optionColor = prefix + "color1";
GValue colorValue = G_VALUE_INIT; std::string optionImageStyle = prefix + "image-style";
GPtrArray *colorArr = g_ptr_array_sized_new(4); std::string optionColorStyle = prefix + "color-style";
GType colorArrType = g_type_from_name("GPtrArray_GValue_");
//TODO:fix later xfconf_channel_set_string(bgchannel, optionImage.c_str(), concatPath.c_str());
//if (!colorArrType) { xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), 0);
std::stringstream colorCommand; xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), 4);
colorCommand << "xfconf-query -c xfce4-desktop -n -p " << optionColor
<< " -t uint -t uint -t uint -t uint -s " << ub GPtrArray *colorArr = g_ptr_array_sized_new(4);
<< " -s " << ug << " -s " << ub << " -s " << alpha; GValue *vr = g_new0(GValue, 1);
Debug() << "xfconf-query -c xfce4-desktop -n -p " << optionColor GValue *vg = g_new0(GValue, 1);
<< " -t uint -t uint -t uint -t uint -s " << ub GValue *vb = g_new0(GValue, 1);
<< " -s " << ug << " -s " << ub << " -s " << alpha; GValue *va = g_new0(GValue, 1);
int colorCommandRes = system(colorCommand.str().c_str()); g_value_init(vr, G_TYPE_UINT);
defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor); g_value_init(vg, G_TYPE_UINT);
colorArrType = g_type_from_name("GPtrArray_GValue_"); g_value_init(vb, G_TYPE_UINT);
if (!colorArrType) { g_value_init(va, G_TYPE_UINT);
// Let's do some debug output here and skip changing the color g_value_set_uint(vr, ur);
Debug() << "[wallpaperSet] WALLPAPER ERROR: xfconf-query call returned" << colorCommandRes; g_value_set_uint(vg, ug);
return Qnil; g_value_set_uint(vb, ub);
g_value_set_uint(va, alpha);
g_ptr_array_add(colorArr, vr);
g_ptr_array_add(colorArr, vg);
g_ptr_array_add(colorArr, vb);
g_ptr_array_add(colorArr, va);
if (!xfconf_channel_set_arrayv(bgchannel, optionColor.c_str(), colorArr)) {
Debug() << "[wallpaperSet] WALLPAPER ERROR: xfconf_channel_set_arrayv failed for" << optionColor;
} }
//} g_value_unset(vr);
g_value_init(&colorValue, colorArrType); g_value_unset(vg);
GValue *vr = g_new0(GValue, 1); g_value_unset(vb);
GValue *vg = g_new0(GValue, 1); g_value_unset(va);
GValue *vb = g_new0(GValue, 1); g_free(vr);
GValue *va = g_new0(GValue, 1); g_free(vg);
g_value_init(vr, G_TYPE_UINT); g_free(vb);
g_value_init(vg, G_TYPE_UINT); g_free(va);
g_value_init(vb, G_TYPE_UINT); g_ptr_array_free(colorArr, TRUE);
g_value_init(va, G_TYPE_UINT); }
g_value_set_uint(vr, ur); system("xfdesktop --reload &");
g_value_set_uint(vg, ug);
g_value_set_uint(vb, ub);
g_value_set_uint(va, alpha);
g_ptr_array_add(colorArr, vr);
g_ptr_array_add(colorArr, vg);
g_ptr_array_add(colorArr, vb);
g_ptr_array_add(colorArr, va);
g_value_set_boxed(&colorValue, colorArr);
xfconf_channel_set_property(bgchannel, optionColor.c_str(), &colorValue);
} else if (desktop == "kde") { } else if (desktop == "kde") {
std::stringstream command; std::stringstream command;
std::string concatPath(gameDirStr + path); std::string concatPath(gameDirStr + path);
@ -622,26 +664,38 @@ RB_METHOD(wallpaperReset){
g_settings_set_string(bgsetting, "primary-color", defPrimaryColor.c_str()); g_settings_set_string(bgsetting, "primary-color", defPrimaryColor.c_str());
g_settings_set_string(bgsetting, "color-shading-type", defColorShading.c_str()); g_settings_set_string(bgsetting, "color-shading-type", defColorShading.c_str());
} else if (desktop == "xfce") { } else if (desktop == "xfce") {
if (defColorExists) { for (const std::string &prefix : xfceMonitorPrefixes) {
xfconf_channel_set_property(bgchannel, optionColor.c_str(), &defColor); std::string optionImage = prefix + "last-image";
} else { std::string optionColor = prefix + "color1";
xfconf_channel_reset_property(bgchannel, optionColor.c_str(), false); std::string optionImageStyle = prefix + "image-style";
std::string optionColorStyle = prefix + "color-style";
if (defXfceColorExists[prefix]) {
xfconf_channel_set_property(bgchannel, optionColor.c_str(), &defXfceColor[prefix]);
} else {
xfconf_channel_reset_property(bgchannel, optionColor.c_str(), false);
}
if (defXfcePictureURI[prefix] == "") {
xfconf_channel_reset_property(bgchannel, optionImage.c_str(), false);
} else {
xfconf_channel_set_string(bgchannel, optionImage.c_str(), defXfcePictureURI[prefix].c_str());
}
if (defXfcePictureStyle[prefix] == -1) {
xfconf_channel_reset_property(bgchannel, optionImageStyle.c_str(), false);
} else {
xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), defXfcePictureStyle[prefix]);
}
if (defXfceColorStyle[prefix] == -1) {
xfconf_channel_reset_property(bgchannel, optionColorStyle.c_str(), false);
} else {
xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), defXfceColorStyle[prefix]);
}
} }
if (defPictureURI == "") { if (xfceHasSingleWorkspaceProps && xfceSingleWorkspaceMode) {
xfconf_channel_reset_property(bgchannel, optionImage.c_str(), false); xfconf_channel_set_bool(bgchannel, "/backdrop/single-workspace-mode", false);
} else { xfconf_channel_set_bool(bgchannel, "/backdrop/single-workspace-mode", true);
xfconf_channel_set_string(bgchannel, optionImage.c_str(), defPictureURI.c_str());
}
if (defPictureStyle == -1) {
xfconf_channel_reset_property(bgchannel, optionImageStyle.c_str(), false);
} else {
xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), defPictureStyle);
}
if (defColorStyle == -1) {
xfconf_channel_reset_property(bgchannel, optionColorStyle.c_str(), false);
} else {
xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), defColorStyle);
} }
system("xfdesktop --reload &");
} else if (desktop == "kde") { } else if (desktop == "kde") {
std::stringstream command; std::stringstream command;
command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" << command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" <<