SNI: Gracefully handle empty IconPixmap

An empty pixmap caused extreme flickering.
https://github.com/scorpion-26/gBar/issues/38
This commit is contained in:
scorpion-26 2023-08-22 22:30:38 +02:00
parent b246e9fad4
commit a15bb1e17e

View file

@ -78,6 +78,8 @@ namespace SNI
// g_variant_unref(param); // g_variant_unref(param);
return res; return res;
}; };
bool hasPixmap = false;
GVariant* iconPixmap = getProperty("IconPixmap"); GVariant* iconPixmap = getProperty("IconPixmap");
if (iconPixmap) if (iconPixmap)
{ {
@ -88,44 +90,51 @@ namespace SNI
GVariantIter* arrIter = nullptr; GVariantIter* arrIter = nullptr;
g_variant_get(arr, "a(iiay)", &arrIter); g_variant_get(arr, "a(iiay)", &arrIter);
int width; if (g_variant_iter_n_children(arrIter) == 3)
int height;
GVariantIter* data = nullptr;
g_variant_iter_next(arrIter, "(iiay)", &width, &height, &data);
LOG("SNI: Width: " << width);
LOG("SNI: Height: " << height);
item.w = width;
item.h = height;
item.iconData = new uint8_t[width * height * 4];
uint8_t px = 0;
int i = 0;
while (g_variant_iter_next(data, "y", &px))
{ {
item.iconData[i] = px; int width;
i++; int height;
} GVariantIter* data = nullptr;
for (int i = 0; i < width * height; i++) g_variant_iter_next(arrIter, "(iiay)", &width, &height, &data);
{
struct Px LOG("SNI: Width: " << width);
LOG("SNI: Height: " << height);
item.w = width;
item.h = height;
item.iconData = new uint8_t[width * height * 4];
uint8_t px = 0;
int i = 0;
while (g_variant_iter_next(data, "y", &px))
{ {
// This should be bgra... item.iconData[i] = px;
// Since source is ARGB32 in network order(=big-endian) i++;
// and x86 Linux is little-endian, we *should* swap b and r... }
uint8_t a, r, g, b; for (int i = 0; i < width * height; i++)
}; {
Px& pixel = ((Px*)item.iconData)[i]; struct Px
// Swap to create rgba {
pixel = {pixel.r, pixel.g, pixel.b, pixel.a}; // This should be bgra...
} // Since source is ARGB32 in network order(=big-endian)
// and x86 Linux is little-endian, we *should* swap b and r...
uint8_t a, r, g, b;
};
Px& pixel = ((Px*)item.iconData)[i];
// Swap to create rgba
pixel = {pixel.r, pixel.g, pixel.b, pixel.a};
}
g_variant_iter_free(data); g_variant_iter_free(data);
g_variant_iter_free(arrIter); g_variant_iter_free(arrIter);
hasPixmap = true;
}
g_variant_unref(arr); g_variant_unref(arr);
g_variant_unref(iconPixmap); g_variant_unref(iconPixmap);
} }
else
// Pixmap querying has failed, try IconName
if (!hasPixmap)
{ {
auto findIconWithoutPath = [](const char* iconName) -> std::string auto findIconWithoutPath = [](const char* iconName) -> std::string
{ {