fix crash when loading image icons

This commit is contained in:
Tom Beckmann 2014-06-23 21:21:37 +02:00
parent 9878c7b7d9
commit bd13e5d929
5 changed files with 80 additions and 23 deletions

View File

@ -42,6 +42,7 @@ libgala_notify_la_VALASOURCES = \
nodist_libgala_notify_la_SOURCES = \
$(BUILT_SOURCES) \
$(libgala_notify_la_VALASOURCES:.vala=.c) \
pixbuf-dbus-util.c \
$(NULL)
libgala_notify_la_vala.stamp: $(libgala_notify_la_VALASOURCES)

View File

@ -39,6 +39,7 @@ namespace Gala.Plugins.Notify
public string[] notification_actions { get; construct set; }
public uint64 relevancy_time { get; private set; }
public bool being_destroyed { get; private set; default = false; }
Text summary_label;
Text body_label;
@ -129,6 +130,7 @@ namespace Gala.Plugins.Notify
{
opacity = 0;
being_destroyed = true;
get_transition ("opacity").completed.connect (() => destroy ());
}

View File

@ -37,11 +37,10 @@ namespace Gala.Plugins.Notify
if (animation_counter == 0)
animations_changed (true);
foreach (var child in get_children ()) {
var notification = (Notification) child;
if (notification.id == id) {
if (notification.id == id && !notification.being_destroyed) {
notification.update (summary, body, icon, expire_timeout, actions);
var transition = notification.get_transition ("update");

View File

@ -19,6 +19,9 @@ using Meta;
namespace Gala.Plugins.Notify
{
[CCode (cname = "get_pixbuf_from_dbus_variant")]
public extern Gdk.Pixbuf get_pixbuf_from_dbus_variant (Variant variant);
public enum NotificationUrgency {
LOW = 0,
NORMAL = 1,
@ -96,31 +99,24 @@ namespace Gala.Plugins.Notify
Gdk.Pixbuf? pixbuf = null;
var size = Notification.ICON_SIZE;
if (hints.contains ("image_data")) {
if (hints.contains ("image_data") || hints.contains ("image-data")) {
int width;
int height;
int rowstride;
bool has_alpha;
int bits_per_sample;
int channels;
weak Array<uint8> data;
var image = hints.contains ("image_data") ?
hints.lookup ("image_data") : hints.lookup ("image-data");
hints.lookup ("image_data").get ("(iiibiiay)", out width, out height, out rowstride,
out has_alpha, out bits_per_sample, out channels, out data, uint.MAX);
pixbuf = new Gdk.Pixbuf.from_data ((uint8[])data, Gdk.Colorspace.RGB, has_alpha,
bits_per_sample, width, height, rowstride, null);
pixbuf = get_pixbuf_from_dbus_variant (image);
pixbuf = pixbuf.scale_simple (size, size, Gdk.InterpType.HYPER);
} else if (hints.contains ("image-path")) {
} else if (hints.contains ("image-path") || hints.contains ("image_path")) {
var image_path = hints.lookup ("image-path").get_string ();
var image_path = (hints.contains ("image-path") ?
hints.lookup ("image-path") : hints.lookup ("image_path")).get_string ();
try {
if (image_path.has_prefix ("file://")) {
pixbuf = new Gdk.Pixbuf.from_file_at_scale (image_path, size, size, true);
if (image_path.has_prefix ("file://") || image_path.has_prefix ("/")) {
var file_path = File.new_for_commandline_arg (image_path).get_path ();
pixbuf = new Gdk.Pixbuf.from_file_at_scale (file_path, size, size, true);
} else {
pixbuf = Gtk.IconTheme.get_default ().load_icon (image_path, size, 0);
}
@ -135,16 +131,17 @@ namespace Gala.Plugins.Notify
} else if (hints.contains ("icon_data")) {
print ("IMPLEMENT ICON_DATA!!!!!!!!\n");
/*Gdk.Pixdata data = {};
Gdk.Pixdata data = {};
try {
if (data.deserialize ((uint8[])hints.lookup ("image-data").get_data ()))
tex.set_from_pixbuf (Gdk.Pixbuf.from_pixdata (data));
if (data.deserialize ((uint8[])hints.lookup ("icon_data").get_data ()))
pixbuf = Gdk.Pixbuf.from_pixdata (data);
else
warning ("Error while deserializing icon_data");
} catch (Error e) { warning (e.message); }*/
} catch (Error e) { warning (e.message); }
}
if (pixbuf == null) {
try {
pixbuf = Gtk.IconTheme.get_default ().load_icon (app.down (), size, 0);
} catch (Error e) {

View File

@ -0,0 +1,58 @@
#include <glib-object.h>
#include <glib-object.h>
#include <gdk/gdk.h>
// copied from notify-osd /src/stack.c with some minor changes
GdkPixbuf *
get_pixbuf_from_dbus_variant (GVariant *variant)
{
GValue data = G_VALUE_INIT;
GType dbus_icon_t;
GArray *pixels;
int width, height, rowstride, bits_per_sample, n_channels, size;
gboolean has_alpha;
guchar *copy;
GdkPixbuf *pixbuf = NULL;
g_return_val_if_fail (variant != NULL, NULL);
dbus_icon_t = dbus_g_type_get_struct ("GValueArray",
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_BOOLEAN,
G_TYPE_INT,
G_TYPE_INT,
dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR),
G_TYPE_INVALID);
dbus_g_value_parse_g_variant (variant, &data);
if (G_VALUE_HOLDS (&data, dbus_icon_t)) {
dbus_g_type_struct_get (&data,
0, &width,
1, &height,
2, &rowstride,
3, &has_alpha,
4, &bits_per_sample,
5, &n_channels,
6, &pixels,
G_MAXUINT);
size = (height - 1) * rowstride + width *
((n_channels * bits_per_sample + 7) / 8);
copy = (guchar *) g_memdup (pixels->data, size);
pixbuf = gdk_pixbuf_new_from_data(copy, GDK_COLORSPACE_RGB,
has_alpha,
bits_per_sample,
width, height,
rowstride,
(GdkPixbufDestroyNotify)g_free,
NULL);
}
return pixbuf;
}