diff options
-rw-r--r-- | .bzrignore | 1 | ||||
-rw-r--r-- | debian/changelog | 8 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/app-gtk-menu-item.c | 57 | ||||
-rw-r--r-- | src/app-gtk-menu-item.h | 32 | ||||
-rw-r--r-- | src/app-menu-item.c | 10 | ||||
-rw-r--r-- | src/dbus-data.h | 2 | ||||
-rw-r--r-- | src/indicator-messages.c | 65 |
8 files changed, 172 insertions, 5 deletions
@@ -22,3 +22,4 @@ indicator-messages-service-activate src/messages-service-client.h src/messages-service-server.h po/indicator-messages.pot +src/libmessaging_la-app-gtk-menu-item.lo diff --git a/debian/changelog b/debian/changelog index 97f43c3..2d4bc80 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +indicator-messages (0.3.4-0ubuntu1~ppa2~running1) UNRELEASED; urgency=low + + * Upstream merge + * Show which applications are running with a small icon + next to their entry. + + -- Ted Gould <ted@ubuntu.com> Tue, 23 Mar 2010 16:12:24 -0500 + indicator-messages (0.3.4-0ubuntu1~ppa1) lucid; urgency=low * Upstream release 0.3.4 diff --git a/src/Makefile.am b/src/Makefile.am index c96ef2d..32f0b38 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,8 @@ libexec_PROGRAMS = indicator-messages-service messaginglibdir = $(INDICATORDIR) messaginglib_LTLIBRARIES = libmessaging.la libmessaging_la_SOURCES = \ + app-gtk-menu-item.h \ + app-gtk-menu-item.c \ indicator-messages.c \ messages-service-client.h \ dbus-data.h diff --git a/src/app-gtk-menu-item.c b/src/app-gtk-menu-item.c new file mode 100644 index 0000000..9a34f16 --- /dev/null +++ b/src/app-gtk-menu-item.c @@ -0,0 +1,57 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app-gtk-menu-item.h" + +typedef struct _AppGtkMenuItemPrivate AppGtkMenuItemPrivate; +struct _AppGtkMenuItemPrivate { + int dummy; +}; + +#define APP_GTK_MENU_ITEM_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_GTK_MENU_ITEM_TYPE, AppGtkMenuItemPrivate)) + +static void app_gtk_menu_item_class_init (AppGtkMenuItemClass *klass); +static void app_gtk_menu_item_init (AppGtkMenuItem *self); +static void app_gtk_menu_item_dispose (GObject *object); +static void app_gtk_menu_item_finalize (GObject *object); + +G_DEFINE_TYPE (AppGtkMenuItem, app_gtk_menu_item, GTK_TYPE_CHECK_MENU_ITEM); + +static void +app_gtk_menu_item_class_init (AppGtkMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (AppGtkMenuItemPrivate)); + + object_class->dispose = app_gtk_menu_item_dispose; + object_class->finalize = app_gtk_menu_item_finalize; + + return; +} + +static void +app_gtk_menu_item_init (AppGtkMenuItem *self) +{ + + return; +} + +static void +app_gtk_menu_item_dispose (GObject *object) +{ + + G_OBJECT_CLASS (app_gtk_menu_item_parent_class)->dispose (object); + return; +} + +static void +app_gtk_menu_item_finalize (GObject *object) +{ + + + G_OBJECT_CLASS (app_gtk_menu_item_parent_class)->finalize (object); + return; +} diff --git a/src/app-gtk-menu-item.h b/src/app-gtk-menu-item.h new file mode 100644 index 0000000..feb3139 --- /dev/null +++ b/src/app-gtk-menu-item.h @@ -0,0 +1,32 @@ +#ifndef __APP_GTK_MENU_ITEM_H__ +#define __APP_GTK_MENU_ITEM_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define APP_GTK_MENU_ITEM_TYPE (app_gtk_menu_item_get_type ()) +#define APP_GTK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_GTK_MENU_ITEM_TYPE, AppGtkMenuItem)) +#define APP_GTK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APP_GTK_MENU_ITEM_TYPE, AppGtkMenuItemClass)) +#define IS_APP_GTK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APP_GTK_MENU_ITEM_TYPE)) +#define IS_APP_GTK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APP_GTK_MENU_ITEM_TYPE)) +#define APP_GTK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APP_GTK_MENU_ITEM_TYPE, AppGtkMenuItemClass)) + +typedef struct _AppGtkMenuItem AppGtkMenuItem; +typedef struct _AppGtkMenuItemClass AppGtkMenuItemClass; + +struct _AppGtkMenuItemClass { + GtkCheckMenuItemClass parent_class; +}; + +struct _AppGtkMenuItem { + GtkCheckMenuItem parent; +}; + +GType app_gtk_menu_item_get_type (void); + +G_END_DECLS + +#endif diff --git a/src/app-menu-item.c b/src/app-menu-item.c index 7db72bf..a47c073 100644 --- a/src/app-menu-item.c +++ b/src/app-menu-item.c @@ -210,6 +210,8 @@ app_menu_item_new (IndicateListener * listener, IndicateListenerServer * server) /* Can not ref as not real GObject */ priv->server = server; + dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, APPLICATION_MENUITEM_TYPE); + /* Set up listener signals */ g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_SERVER_COUNT_CHANGED, G_CALLBACK(count_changed), self); @@ -244,10 +246,10 @@ update_label (AppMenuItem * self) /* TRANSLATORS: This is the name of the program and the number of indicators. So it would read something like "Mail Client (5)" */ gchar * label = g_strdup_printf(_("%s (%d)"), _(name), priv->unreadcount); - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, label); + dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_NAME, label); g_free(label); } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, _(name)); + dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_NAME, _(name)); } return; @@ -318,10 +320,10 @@ desktop_cb (IndicateListener * listener, IndicateListenerServer * server, gchar if (def_icon == NULL) { GIcon * icon = g_app_info_get_icon(priv->appinfo); gchar * iconstr = g_icon_to_string(icon); - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ICON_NAME, iconstr); + dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_ICON, iconstr); g_free(iconstr); } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ICON_NAME, def_icon); + dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_ICON, def_icon); } g_signal_emit(G_OBJECT(self), signals[NAME_CHANGED], 0, app_menu_item_get_name(self), TRUE); diff --git a/src/dbus-data.h b/src/dbus-data.h index e3d9fd5..c16b2b5 100644 --- a/src/dbus-data.h +++ b/src/dbus-data.h @@ -10,7 +10,7 @@ #define APPLICATION_MENUITEM_TYPE "application-item" #define APPLICATION_MENUITEM_PROP_NAME "app-name" -#define APPLICATION_MENUITEM_PROP_COUNT "app-count" +#define APPLICATION_MENUITEM_PROP_ICON "app-icon" #define INDICATOR_MENUITEM_TYPE "indicator-item" #define INDICATOR_MENUITEM_PROP_LABEL "indicator-label" diff --git a/src/indicator-messages.c b/src/indicator-messages.c index f6b2084..2387be4 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -207,6 +207,70 @@ setup_icon_proxy (gpointer userdata) return FALSE; } +/* Sets the label when it changes. */ +static void +application_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, gpointer user_data) +{ + if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_NAME)) { + /* Set the main label */ + if (GTK_IS_LABEL(user_data)) { + gtk_label_set_text(GTK_LABEL(user_data), g_value_get_string(value)); + } + } + + return; +} + +/* Builds a menu item representing a running application in the + messaging menu */ +static gboolean +new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_image_menu_item_new()); + + gint padding = 4; + gtk_widget_style_get(GTK_WIDGET(gmi), "horizontal-padding", &padding, NULL); + + GtkWidget * hbox = gtk_hbox_new(FALSE, 0); + + /* Set the minimum size, we always want it to take space */ + gint width, height; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + + GtkWidget * icon = gtk_image_new_from_icon_name(dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_ICON), GTK_ICON_SIZE_MENU); + gtk_widget_set_size_request(icon, width, height); + gtk_misc_set_alignment(GTK_MISC(icon), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, padding); + gtk_widget_show(icon); + + /* Application name in a label */ + GtkWidget * label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_LABEL)); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, padding); + gtk_widget_show(label); + + /* Insert the hbox */ + gtk_container_add(GTK_CONTAINER(gmi), hbox); + gtk_widget_show(hbox); + + /* Build up the running icon */ + GtkWidget * running_icon = gtk_image_new_from_icon_name("application-running", GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gmi), running_icon); + gtk_widget_show(running_icon); + + /* Make sure it always appears */ + gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(gmi), TRUE); + + /* Attach some of the standard GTK stuff */ + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); + + /* Make sure we can handle the label changing */ + g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(application_prop_change_cb), label); + + return TRUE; +} + + typedef struct _indicator_item_t indicator_item_t; struct _indicator_item_t { GtkWidget * icon; @@ -380,6 +444,7 @@ get_menu (IndicatorObject * io) DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), INDICATOR_MENUITEM_TYPE, new_indicator_item); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPLICATION_MENUITEM_TYPE, new_application_item); return GTK_MENU(menu); } |