1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

refactor(systemtrayicon): unify QIcon to GdkPixbuf conversion

Also simplify the memory management by using the C++ allocator and by
using the bytes directly as passed to the free callback instead of
passing it again as user data.
This commit is contained in:
Colomban Wendling 2016-06-14 01:00:28 +02:00
parent eb743b43ff
commit cf4c46ff0b
2 changed files with 27 additions and 60 deletions

View File

@ -116,6 +116,26 @@ QString SystemTrayIcon::extractIconToFile(QIcon icon, QString name)
return iconPath; return iconPath;
} }
#if defined(ENABLE_SYSTRAY_GTK_BACKEND) || defined(ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND)
GdkPixbuf* SystemTrayIcon::convertQIconToPixbuf(const QIcon &icon)
{
void (*callbackFreeImage)(guchar*, gpointer) =
[](guchar* image_bytes, gpointer)
{
delete[] image_bytes;
};
QImage image = icon.pixmap(64, 64).toImage();
if (image.format() != QImage::Format_RGBA8888_Premultiplied)
image = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
guchar* image_bytes = new guchar[image.byteCount()];
memcpy(image_bytes, image.bits(), image.byteCount());
return gdk_pixbuf_new_from_data(image_bytes, GDK_COLORSPACE_RGB, image.hasAlphaChannel(),
8, image.width(), image.height(), image.bytesPerLine(),
callbackFreeImage, NULL);
}
#endif
void SystemTrayIcon::setContextMenu(QMenu* menu) void SystemTrayIcon::setContextMenu(QMenu* menu)
{ {
if (false); if (false);
@ -145,21 +165,7 @@ void SystemTrayIcon::setContextMenu(QMenu* menu)
item = gtk_menu_item_new_with_label(aText.toStdString().c_str()); item = gtk_menu_item_new_with_label(aText.toStdString().c_str());
else else
{ {
void (*callbackFreeImage)(guchar*, gpointer) = GdkPixbuf* pixbuf = convertQIconToPixbuf(a->icon());
[](guchar*, gpointer image_bytes)
{
free(reinterpret_cast<guchar*>(image_bytes));
};
QImage image = a->icon().pixmap(64, 64).toImage();
if (image.format() != QImage::Format_RGBA8888_Premultiplied)
image = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
guchar* image_bytes = (guchar*)malloc(image.byteCount());
memcpy(image_bytes, image.bits(), image.byteCount());
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image_bytes, GDK_COLORSPACE_RGB, image.hasAlphaChannel(),
8, image.width(), image.height(), image.bytesPerLine(),
callbackFreeImage, image_bytes);
item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str()); item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str());
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf(pixbuf)); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf(pixbuf));
gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE); gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE);
@ -195,21 +201,7 @@ void SystemTrayIcon::setContextMenu(QMenu* menu)
item = gtk_menu_item_new_with_label(aText.toStdString().c_str()); item = gtk_menu_item_new_with_label(aText.toStdString().c_str());
else else
{ {
void (*callbackFreeImage)(guchar*, gpointer) = GdkPixbuf* pixbuf = convertQIconToPixbuf(a->icon());
[](guchar*, gpointer image_bytes)
{
free(reinterpret_cast<guchar*>(image_bytes));
};
QImage image = a->icon().pixmap(64, 64).toImage();
if (image.format() != QImage::Format_RGBA8888_Premultiplied)
image = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
guchar* image_bytes = (guchar*)malloc(image.byteCount());
memcpy(image_bytes, image.bits(), image.byteCount());
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image_bytes, GDK_COLORSPACE_RGB, image.hasAlphaChannel(),
8, image.width(), image.height(), image.bytesPerLine(),
callbackFreeImage, image_bytes);
item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str()); item = gtk_image_menu_item_new_with_label(aText.toStdString().c_str());
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf(pixbuf)); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf(pixbuf));
gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE); gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item),TRUE);
@ -333,21 +325,7 @@ void SystemTrayIcon::setIcon(QIcon &icon)
#ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND #ifdef ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND
else if (backendType == SystrayBackendType::StatusNotifier) else if (backendType == SystrayBackendType::StatusNotifier)
{ {
void (*callbackFreeImage)(guchar*, gpointer) = GdkPixbuf* pixbuf = convertQIconToPixbuf(icon);
[](guchar*, gpointer image_bytes)
{
free(reinterpret_cast<guchar*>(image_bytes));
};
QImage image = icon.pixmap(64, 64).toImage();
if (image.format() != QImage::Format_RGBA8888_Premultiplied)
image = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
guchar* image_bytes = (guchar*)malloc(image.byteCount());
memcpy(image_bytes, image.bits(), image.byteCount());
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image_bytes, GDK_COLORSPACE_RGB, image.hasAlphaChannel(),
8, image.width(), image.height(), image.bytesPerLine(),
callbackFreeImage, image_bytes);
status_notifier_set_from_pixbuf(statusNotifier, STATUS_NOTIFIER_ICON, pixbuf); status_notifier_set_from_pixbuf(statusNotifier, STATUS_NOTIFIER_ICON, pixbuf);
g_object_unref(pixbuf); g_object_unref(pixbuf);
} }
@ -355,21 +333,7 @@ void SystemTrayIcon::setIcon(QIcon &icon)
#ifdef ENABLE_SYSTRAY_GTK_BACKEND #ifdef ENABLE_SYSTRAY_GTK_BACKEND
else if (backendType == SystrayBackendType::GTK) else if (backendType == SystrayBackendType::GTK)
{ {
void (*callbackFreeImage)(guchar*, gpointer) = GdkPixbuf* pixbuf = convertQIconToPixbuf(icon);
[](guchar*, gpointer image_bytes)
{
free(reinterpret_cast<guchar*>(image_bytes));
};
QImage image = icon.pixmap(64, 64).toImage();
if (image.format() != QImage::Format_RGBA8888_Premultiplied)
image = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
guchar* image_bytes = (guchar*)malloc(image.byteCount());
memcpy(image_bytes, image.bits(), image.byteCount());
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(image_bytes, GDK_COLORSPACE_RGB, image.hasAlphaChannel(),
8, image.width(), image.height(), image.bytesPerLine(),
callbackFreeImage, image_bytes);
gtk_status_icon_set_from_pixbuf(gtkIcon, pixbuf); gtk_status_icon_set_from_pixbuf(gtkIcon, pixbuf);
g_object_unref(pixbuf); g_object_unref(pixbuf);
} }

View File

@ -44,6 +44,9 @@ signals:
private: private:
QString extractIconToFile(QIcon icon, QString name="icon"); QString extractIconToFile(QIcon icon, QString name="icon");
#if defined(ENABLE_SYSTRAY_GTK_BACKEND) || defined(ENABLE_SYSTRAY_STATUSNOTIFIER_BACKEND)
static GdkPixbuf* convertQIconToPixbuf(const QIcon &icon);
#endif
private: private:
SystrayBackendType backendType; SystrayBackendType backendType;