[Galago-commits] r2821 - in trunk/libnotify: . libnotify

galago-commits at freedesktop.org galago-commits at freedesktop.org
Sun Jun 4 17:49:02 PDT 2006


Author: chipx86
Date: 2006-06-04 17:48:56 -0700 (Sun, 04 Jun 2006)
New Revision: 2821

Modified:
   trunk/libnotify/ChangeLog
   trunk/libnotify/NEWS
   trunk/libnotify/libnotify/notification.c
   trunk/libnotify/libnotify/notification.h
Log:
Patch by chpe to add support for using the new GtkStatusIcon in GTK+ 2.9.x. These functions are #ifdef'd to only be provided in supported versions of GTK. The patch also added support for GObject properties on the NotifyNotification objects. This closes ticket #60.


Modified: trunk/libnotify/ChangeLog
===================================================================
--- trunk/libnotify/ChangeLog	2006-06-04 23:12:30 UTC (rev 2820)
+++ trunk/libnotify/ChangeLog	2006-06-05 00:48:56 UTC (rev 2821)
@@ -1,3 +1,12 @@
+Sun Jun 04 17:44:27 PDT 2006  Christian Hammond <chipx86 at chipx86.com>
+
+	* libnotify/notification.c:
+	* libnotify/notification.h:
+	  - Patch by chpe to add support for using the new GtkStatusIcon in
+	    GTK+ 2.9.x. These functions are #ifdef'd to only be provided in
+	    supported versions of GTK. The patch also added support for GObject
+		properties on the NotifyNotification objects. This closes ticket #60.
+
 Sun Jun 04 16:12:05 PDT 2006  Christian Hammond <chipx86 at chipx86.com>
 
 	* libnotify/notify.c:

Modified: trunk/libnotify/NEWS
===================================================================
--- trunk/libnotify/NEWS	2006-06-04 23:12:30 UTC (rev 2820)
+++ trunk/libnotify/NEWS	2006-06-05 00:48:56 UTC (rev 2821)
@@ -1,3 +1,10 @@
+version 0.4.1:
+	* Added support for attaching to a GtkStatusIcon. Patch by chpe. (Bug #60)
+	* Added GObject properties to NotifyNotification. Patch by chpe. (Bug #60)
+	* Fixed up libnotify.pc to support dependencies correctly. (Bug #58)
+	* Fixed notify_uninit() to properly set _initted to FALSE after being
+	  called. (Bug #56)
+
 version 0.4.0 (26-April-2006):
 	* Patch by M.S. to switch notify-send to use GOption instead of popt,
 	  to add -v, --version, -h, and --hint options, and to rename

Modified: trunk/libnotify/libnotify/notification.c
===================================================================
--- trunk/libnotify/libnotify/notification.c	2006-06-04 23:12:30 UTC (rev 2820)
+++ trunk/libnotify/libnotify/notification.c	2006-06-05 00:48:56 UTC (rev 2821)
@@ -26,10 +26,23 @@
 #include <libnotify/notify.h>
 #include <libnotify/internal.h>
 
+#include <gtk/gtkversion.h>
+#if GTK_CHECK_VERSION(2, 9, 2)
+# define HAVE_STATUS_ICON
+# include <gtk/gtkstatusicon.h>
+#endif
+
 #define CHECK_DBUS_VERSION(major, minor) \
 	(DBUS_MAJOR_VER > (major) || \
 	 (DBUS_MAJOR_VER == (major) && DBUS_MINOR_VER >= (minor)))
 
+#if !defined(G_PARAM_STATIC_NAME) && !defined(G_PARAM_STATIC_NICK) && \
+    !defined(G_PARAM_STATIC_BLURB)
+# define G_PARAM_STATIC_NAME 0
+# define G_PARAM_STATIC_NICK 0
+# define G_PARAM_STATIC_BLURB 0
+#endif
+
 static void notify_notification_class_init(NotifyNotificationClass *klass);
 static void notify_notification_init(NotifyNotification *sp);
 static void notify_notification_finalize(GObject *object);
@@ -69,8 +82,9 @@
 	GHashTable *hints;
 
 	GtkWidget *attached_widget;
-	gint widget_old_x;
-	gint widget_old_y;
+#ifdef HAVE_STATUS_ICON
+	GtkStatusIcon *status_icon;
+#endif
 
 	gboolean has_nondefault_actions;
 	gboolean updates_pending;
@@ -83,11 +97,39 @@
 	LAST_SIGNAL
 };
 
+enum
+{
+	PROP_0,
+	PROP_SUMMARY,
+	PROP_BODY,
+	PROP_ICON_NAME,
+	PROP_ATTACH_WIDGET,
+	PROP_STATUS_ICON
+};
+
+static void notify_notification_set_property(GObject *object, guint prop_id,
+											 const GValue *value,
+											 GParamSpec *pspec);
+static void notify_notification_get_property(GObject *object, guint prop_id,
+											 GValue *value, GParamSpec *pspec);
 static guint signals[LAST_SIGNAL] = { 0 };
 static GObjectClass *parent_class = NULL;
 
-G_DEFINE_TYPE(NotifyNotification, notify_notification, G_TYPE_OBJECT);
+G_DEFINE_TYPE(NotifyNotification, notify_notification, G_TYPE_OBJECT)
 
+static GObject *
+notify_notification_constructor(GType type,
+								guint n_construct_properties,
+								GObjectConstructParam *construct_params)
+{
+	GObject *object = parent_class->constructor(type, n_construct_properties,
+												construct_params);
+
+	_notify_cache_add_notification(NOTIFY_NOTIFICATION(object));
+
+	return object;
+}
+
 static void
 notify_notification_class_init(NotifyNotificationClass *klass)
 {
@@ -95,6 +137,9 @@
 
 	parent_class = g_type_class_peek_parent(klass);
 
+	object_class->constructor = notify_notification_constructor;
+	object_class->get_property = notify_notification_get_property;
+	object_class->set_property = notify_notification_set_property;
 	object_class->finalize = notify_notification_finalize;
 
 	/* Create signals here: */
@@ -105,9 +150,160 @@
 					 G_STRUCT_OFFSET(NotifyNotificationClass, closed),
 					 NULL, NULL,
 					 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+	g_object_class_install_property
+			(object_class,
+			PROP_SUMMARY,
+			g_param_spec_string("summary",
+								"Summary",
+								"Summary",
+								NULL,
+								G_PARAM_READWRITE |
+								G_PARAM_CONSTRUCT |
+								G_PARAM_STATIC_NAME |
+								G_PARAM_STATIC_NICK |
+								G_PARAM_STATIC_BLURB));
+
+	g_object_class_install_property
+			(object_class,
+			PROP_BODY,
+			g_param_spec_string("body",
+								"Message Body",
+								"Message body",
+								NULL,
+								G_PARAM_READWRITE |
+								G_PARAM_CONSTRUCT |
+								G_PARAM_STATIC_NAME |
+								G_PARAM_STATIC_NICK |
+								G_PARAM_STATIC_BLURB));
+
+	g_object_class_install_property
+			(object_class,
+			PROP_ICON_NAME,
+			g_param_spec_string("icon-name",
+								"Icon Name",
+								"Icon name",
+								NULL,
+								G_PARAM_READWRITE |
+								G_PARAM_CONSTRUCT |
+								G_PARAM_STATIC_NAME |
+								G_PARAM_STATIC_NICK |
+								G_PARAM_STATIC_BLURB));
+
+	g_object_class_install_property
+			(object_class,
+			PROP_ATTACH_WIDGET,
+			g_param_spec_object("attach-widget",
+								"Attach Widget",
+								"Attach Widget",
+								GTK_TYPE_WIDGET,
+								G_PARAM_READWRITE |
+								G_PARAM_CONSTRUCT |
+								G_PARAM_STATIC_NAME |
+								G_PARAM_STATIC_NICK |
+								G_PARAM_STATIC_BLURB));
+
+#ifdef HAVE_STATUS_ICON
+	g_object_class_install_property
+			(object_class,
+			PROP_STATUS_ICON,
+			g_param_spec_object("status-icon",
+								"Status Icon",
+								"Status Icon",
+								GTK_TYPE_STATUS_ICON,
+								G_PARAM_READWRITE |
+								G_PARAM_CONSTRUCT |
+								G_PARAM_STATIC_NAME |
+								G_PARAM_STATIC_NICK |
+								G_PARAM_STATIC_BLURB));
+#endif /* HAVE_STATUS_ICON */
 }
 
 static void
+notify_notification_set_property(GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+	NotifyNotification *notification = NOTIFY_NOTIFICATION(object);
+	NotifyNotificationPrivate *priv = notification->priv;
+
+	switch (prop_id)
+	{
+		case PROP_SUMMARY:
+			notify_notification_update(notification, g_value_get_string(value),
+									   priv->body, priv->icon_name);
+			break;
+
+		case PROP_BODY:
+			notify_notification_update(notification, priv->summary,
+									   g_value_get_string(value),
+									   priv->icon_name);
+			break;
+
+		case PROP_ICON_NAME:
+			notify_notification_update(notification, priv->summary,
+									   priv->body, g_value_get_string(value));
+			break;
+
+		case PROP_ATTACH_WIDGET:
+			notify_notification_attach_to_widget(notification,
+				g_value_get_object(value));
+			break;
+
+#ifdef HAVE_STATUS_ICON
+		case PROP_STATUS_ICON:
+			notify_notification_attach_to_status_icon(notification,
+				g_value_get_object(value));
+			break;
+#endif
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+notify_notification_get_property(GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+	NotifyNotification *notification = NOTIFY_NOTIFICATION(object);
+	NotifyNotificationPrivate *priv = notification->priv;
+
+	switch (prop_id)
+	{
+		case PROP_SUMMARY:
+			g_value_set_string(value, priv->summary);
+			break;
+
+		case PROP_BODY:
+			g_value_set_string(value, priv->body);
+			break;
+
+		case PROP_ICON_NAME:
+			g_value_set_string(value, priv->icon_name);
+			break;
+
+		case PROP_ATTACH_WIDGET:
+			g_value_set_object(value, priv->attached_widget);
+			break;
+
+#ifdef HAVE_STATUS_ICON
+		case PROP_STATUS_ICON:
+			g_value_set_object(value, priv->status_icon);
+			break;
+#endif
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
 _g_value_free(GValue *value)
 {
 	g_value_unset(value);
@@ -165,6 +361,12 @@
 	if (priv->attached_widget != NULL)
 		g_object_unref(G_OBJECT(priv->attached_widget));
 
+#if HAVE_STATUS_ICON
+    if (priv->status_icon != NULL)
+        g_object_remove_weak_pointer(G_OBJECT(priv->status_icon),
+								     (gpointer)&priv->status_icon);
+#endif
+
 	if (priv->signals_registered)
 	{
 		dbus_g_proxy_disconnect_signal(proxy, "NotificationClosed",
@@ -180,61 +382,59 @@
 	G_OBJECT_CLASS(parent_class)->finalize(object);
 }
 
-static gboolean
+static void
 _notify_notification_update_applet_hints(NotifyNotification *n)
 {
 	NotifyNotificationPrivate *priv = n->priv;
-	gboolean update_pending = FALSE;
+	GdkScreen *screen = NULL;
+	GdkRectangle rect;
 
+#ifdef HAVE_STATUS_ICON
+	if (priv->status_icon != NULL)
+	{
+		if (!gtk_status_icon_get_geometry(priv->status_icon, &screen,
+										  &rect, NULL))
+		{
+			return;
+		}
+	}
+	else
+#endif /* HAVE_STATUS_ICON */
 	if (priv->attached_widget != NULL)
 	{
-		gint x, y, h, w;
 		GtkWidget *widget = priv->attached_widget;
 		GtkRequisition requisition;
 
+		screen = gtk_widget_get_screen(widget);
 		gtk_widget_size_request(widget, &requisition);
-		w = requisition.width;
-		h = requisition.height;
+		rect.width = requisition.width;
+		rect.height = requisition.height;
 
-		gdk_window_get_origin(widget->window, &x, &y);
+		gdk_window_get_origin(widget->window, &rect.x, &rect.y);
 
 		if (GTK_WIDGET_NO_WINDOW(widget))
 		{
-			x += widget->allocation.x;
-			y += widget->allocation.y;
+			rect.x += widget->allocation.x;
+			rect.y += widget->allocation.y;
 		}
 
-		x += widget->allocation.width / 2;
-		y += widget->allocation.height / 2;
-
-		if (x != priv->widget_old_x)
-		{
-			notify_notification_set_hint_int32(n, "x", x);
-			priv->widget_old_x = x;
-
-			update_pending = TRUE;
-		}
-
-		if (y != priv->widget_old_y)
-		{
-			notify_notification_set_hint_int32(n, "y", y);
-			priv->widget_old_y = y;
-
-			update_pending = TRUE;
-		}
+		rect.x += widget->allocation.width / 2;
+		rect.y += widget->allocation.height / 2;
 	}
+	else
+		return;
 
-	return update_pending;
+	notify_notification_set_geometry_hints(n, screen, &rect);
 }
 
 #if 0
-
-/* This is left here just incase we revisit autoupdating
-   One thought would be to check for updates every time the icon
-   is redrawn but we still have to deal with the race conditions
-   that could occure between the server and the client so we will
-   leave this alone for now.
-*/
+/*
+ * This is left here just incase we revisit autoupdating
+ * One thought would be to check for updates every time the icon
+ * is redrawn but we still have to deal with the race conditions
+ * that could occure between the server and the client so we will
+ * leave this alone for now.
+ */
 static gboolean
 _idle_check_updates(void *user_data)
 {
@@ -264,31 +464,33 @@
 notify_notification_new(const gchar *summary, const gchar *body,
 						const gchar *icon, GtkWidget *attach)
 {
-	NotifyNotification *obj;
-
-	g_return_val_if_fail(summary != NULL && *summary != '\0',     NULL);
 	g_return_val_if_fail(attach == NULL || GTK_IS_WIDGET(attach), NULL);
 
-	obj = NOTIFY_NOTIFICATION(g_object_new(NOTIFY_TYPE_NOTIFICATION, NULL));
+	return g_object_new(NOTIFY_TYPE_NOTIFICATION,
+						"summary", summary,
+						"body", body,
+						"icon-name",  icon,
+						"attach-widget", attach,
+						NULL);
+}
 
-	obj->priv->summary = g_strdup(summary);
+#ifdef HAVE_STATUS_ICON
+NotifyNotification *
+notify_notification_new_with_status_icon(const gchar *summary,
+                                         const gchar *message,
+                                         const gchar *icon,
+                                         GtkStatusIcon *status_icon)
+{
+	g_return_val_if_fail(status_icon == NULL || GTK_IS_STATUS_ICON(status_icon), NULL);
 
-	if (body != NULL && *body != '\0')
-		obj->priv->body = g_strdup(body);
-
-	if (icon != NULL && *icon != '\0')
-		obj->priv->icon_name = g_strdup(icon);
-
-	if (attach != NULL)
-	{
-		g_object_ref(G_OBJECT(attach));
-		obj->priv->attached_widget = attach;
-	}
-
-	_notify_cache_add_notification(obj);
-
-	return obj;
+	return g_object_new(NOTIFY_TYPE_NOTIFICATION,
+						"summary", summary,
+						"body", message,
+						"icon-name",  icon,
+						"status-icon", status_icon,
+						NULL);
 }
+#endif /* HAVE_STATUS_ICON */
 
 gboolean
 notify_notification_update(NotifyNotification *notification,
@@ -299,18 +501,29 @@
 	g_return_val_if_fail(NOTIFY_IS_NOTIFICATION(notification), FALSE);
 	g_return_val_if_fail(summary != NULL && *summary != '\0',  FALSE);
 
-	g_free(notification->priv->summary);
-	g_free(notification->priv->body);
-	g_free(notification->priv->icon_name);
+	if (notification->priv->summary != summary)
+	{
+		g_free(notification->priv->summary);
+		notification->priv->summary = g_strdup(summary);
+		g_object_notify(G_OBJECT(notification), "summary");
+	}
 
-	notification->priv->summary = g_strdup(summary);
+	if (notification->priv->body != body)
+	{
+		g_free(notification->priv->body);
+		notification->priv->body =
+			(body != NULL && *body != '\0' ? g_strdup(body) : NULL);
+		g_object_notify(G_OBJECT(notification), "body");
+	}
 
-	if (body != NULL && *body != '\0')
-		notification->priv->body = g_strdup(body);
+	if (notification->priv->icon_name != icon)
+	{
+		g_free(notification->priv->icon_name);
+		notification->priv->icon_name =
+			(icon != NULL && *icon != '\0' ? g_strdup(icon) : NULL);
+		g_object_notify(G_OBJECT(notification), "icon-name");
+	}
 
-	if (icon != NULL && *icon != '\0')
-		notification->priv->icon_name = g_strdup(icon);
-
 	notification->priv->updates_pending = TRUE;
 
 	return TRUE;
@@ -320,16 +533,72 @@
 notify_notification_attach_to_widget(NotifyNotification *notification,
 									 GtkWidget *attach)
 {
-	g_return_if_fail(notification != NULL);
 	g_return_if_fail(NOTIFY_IS_NOTIFICATION(notification));
 
+	if (notification->priv->attached_widget == attach)
+		return;
+
 	if (notification->priv->attached_widget != NULL)
 		g_object_unref(notification->priv->attached_widget);
 
 	notification->priv->attached_widget =
 		(attach != NULL ? g_object_ref(attach) : NULL);
+
+	g_object_notify(G_OBJECT(notification), "attach-widget");
 }
 
+#ifdef HAVE_STATUS_ICON
+void
+notify_notification_attach_to_status_icon(NotifyNotification *notification,
+										  GtkStatusIcon *status_icon)
+{
+	g_return_if_fail(NOTIFY_IS_NOTIFICATION(notification));
+	g_return_if_fail(status_icon == NULL || GTK_IS_STATUS_ICON(status_icon));
+
+	if (notification->priv->status_icon == status_icon)
+		return;
+
+	if (priv->status_icon != NULL)
+	{
+		g_object_remove_weak_pointer(G_OBJECT(priv->status_icon),
+									 (gpointer)&priv->status_icon);
+	}
+
+	priv->status_icon = status_icon;
+
+	if (priv->status_icon != NULL)
+	{
+		g_object_add_weak_pointer(G_OBJECT(priv->status_icon),
+								  (gpointer)&priv->status_icon);
+	}
+
+	g_object_notify(G_OBJECT(notification), "attach-icon");
+}
+#endif /* HAVE_STATUS_ICON */
+
+void
+notify_notification_set_geometry_hints(NotifyNotification *notification,
+									   GdkScreen *screen,
+									   GdkRectangle *rect)
+{
+	char *display_name;
+
+	g_return_if_fail(notification != NULL);
+	g_return_if_fail(NOTIFY_IS_NOTIFICATION(notification));
+	g_return_if_fail(screen != NULL);
+	g_return_if_fail(GDK_IS_SCREEN(screen));
+	g_return_if_fail(rect != NULL);
+
+	notify_notification_set_hint_int32(notification, "x", rect->x);
+	notify_notification_set_hint_int32(notification, "y", rect->y);
+	notify_notification_set_hint_int32(notification, "width", rect->width);
+	notify_notification_set_hint_int32(notification, "height", rect->height);
+
+	display_name = gdk_screen_make_display_name(screen);
+	notify_notification_set_hint_string(notification, "xdisplay", display_name);
+	g_free(display_name);
+}
+
 static void
 _close_signal_handler(DBusGProxy *proxy, guint32 id,
 					  NotifyNotification *notification)
@@ -405,7 +674,7 @@
 		priv->signals_registered = TRUE;
 	}
 
-	/* If attached to a widget, modify x and y in hints */
+	/* If attached to a widget or status icon, modify x and y in hints */
 	_notify_notification_update_applet_hints(notification);
 
 	action_array = _gslist_to_string_array(priv->actions);

Modified: trunk/libnotify/libnotify/notification.h
===================================================================
--- trunk/libnotify/libnotify/notification.h	2006-06-04 23:12:30 UTC (rev 2820)
+++ trunk/libnotify/libnotify/notification.h	2006-06-05 00:48:56 UTC (rev 2821)
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
+#include <gtk/gtkversion.h>
 
 G_BEGIN_DECLS
 
@@ -86,6 +87,11 @@
 											const gchar *message,
 											const gchar *icon,
 											GtkWidget *attach);
+#if GTK_CHECK_VERSION(2, 9, 2)
+NotifyNotification *notify_notification_new_with_status_icon(
+	const gchar *summary, const gchar *message,
+	const gchar *icon, GtkStatusIcon *status_icon);
+#endif
 
 gboolean notify_notification_update(NotifyNotification *notification,
 									const gchar *summary,
@@ -95,6 +101,15 @@
 void notify_notification_attach_to_widget(NotifyNotification* notification,
 										  GtkWidget *attach);
 
+#if GTK_CHECK_VERSION(2, 9, 2)
+void notify_notification_attach_to_status_icon(NotifyNotification *notification,
+                                               GtkStatusIcon *status_icon);
+#endif
+
+void notify_notification_set_geometry_hints(NotifyNotification *notification,
+											GdkScreen *screen,
+											GdkRectangle *rect);
+
 gboolean notify_notification_show(NotifyNotification *notification,
 								  GError **error);
 
@@ -107,8 +122,8 @@
 void notify_notification_set_urgency(NotifyNotification *notification,
 									 NotifyUrgency l);
 
-void notify_notification_set_icon_from_pixbuf(
-	NotifyNotification *notification, GdkPixbuf *icon);
+void notify_notification_set_icon_from_pixbuf(NotifyNotification *notification,
+											  GdkPixbuf *icon);
 
 void notify_notification_set_hint_int32(NotifyNotification *notification,
 										const gchar *key, gint value);



More information about the galago-commits mailing list