aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indicator-messages.c')
-rw-r--r--src/indicator-messages.c410
1 files changed, 332 insertions, 78 deletions
diff --git a/src/indicator-messages.c b/src/indicator-messages.c
index f47eccd..ed6caa6 100644
--- a/src/indicator-messages.c
+++ b/src/indicator-messages.c
@@ -23,11 +23,10 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include <glib.h>
#include <glib-object.h>
+#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <libdbusmenu-gtk/menu.h>
#include <libdbusmenu-gtk/menuitem.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
#include <libindicator/indicator.h>
#include <libindicator/indicator-object.h>
@@ -35,7 +34,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libindicator/indicator-service-manager.h>
#include "dbus-data.h"
-#include "messages-service-client.h"
+#include "gen-messages-service.xml.h"
#define INDICATOR_MESSAGES_TYPE (indicator_messages_get_type ())
#define INDICATOR_MESSAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_MESSAGES_TYPE, IndicatorMessages))
@@ -44,11 +43,17 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define IS_INDICATOR_MESSAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_MESSAGES_TYPE))
#define INDICATOR_MESSAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_MESSAGES_TYPE, IndicatorMessagesClass))
+#define M_PI 3.1415926535897932384626433832795028841971693993751
+
+#define RIGHT_LABEL_FONT_SIZE 12
+#define RIGHT_LABEL_RADIUS 20
+
typedef struct _IndicatorMessages IndicatorMessages;
typedef struct _IndicatorMessagesClass IndicatorMessagesClass;
struct _IndicatorMessagesClass {
IndicatorObjectClass parent_class;
+ void (*update_a11y_desc) (IndicatorServiceManager * service, gpointer * user_data);
};
struct _IndicatorMessages {
@@ -64,8 +69,12 @@ INDICATOR_SET_TYPE(INDICATOR_MESSAGES_TYPE)
/* Globals */
static GtkWidget * main_image = NULL;
-static DBusGProxy * icon_proxy = NULL;
+static GDBusProxy * icon_proxy = NULL;
static GtkSizeGroup * indicator_right_group = NULL;
+static GDBusNodeInfo * bus_node_info = NULL;
+static GDBusInterfaceInfo * bus_interface_info = NULL;
+static const gchar * accessible_desc = NULL;
+static IndicatorObject * indicator = NULL;
/* Prototypes */
static void indicator_messages_class_init (IndicatorMessagesClass *klass);
@@ -74,12 +83,34 @@ static void indicator_messages_dispose (GObject *object);
static void indicator_messages_finalize (GObject *object);
static GtkImage * get_icon (IndicatorObject * io);
static GtkMenu * get_menu (IndicatorObject * io);
+static const gchar * get_accessible_desc (IndicatorObject * io);
static void connection_change (IndicatorServiceManager * sm,
gboolean connected,
gpointer user_data);
G_DEFINE_TYPE (IndicatorMessages, indicator_messages, INDICATOR_OBJECT_TYPE);
+static void
+update_a11y_desc (void)
+{
+ g_return_if_fail(IS_INDICATOR_MESSAGES(indicator));
+
+ GList *entries = indicator_object_get_entries(indicator);
+ IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data;
+
+ entry->accessible_desc = get_accessible_desc(indicator);
+
+ g_signal_emit(G_OBJECT(indicator),
+ INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID,
+ 0,
+ entry,
+ TRUE);
+
+ g_list_free(entries);
+
+ return;
+}
+
/* Initialize the one-timers */
static void
indicator_messages_class_init (IndicatorMessagesClass *klass)
@@ -93,6 +124,25 @@ indicator_messages_class_init (IndicatorMessagesClass *klass)
io_class->get_image = get_icon;
io_class->get_menu = get_menu;
+ io_class->get_accessible_desc = get_accessible_desc;
+
+ if (bus_node_info == NULL) {
+ GError * error = NULL;
+
+ bus_node_info = g_dbus_node_info_new_for_xml(_messages_service, &error);
+ if (error != NULL) {
+ g_error("Unable to parse Messaging Menu Interface description: %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ if (bus_interface_info == NULL) {
+ bus_interface_info = g_dbus_node_info_lookup_interface(bus_node_info, INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE);
+
+ if (bus_interface_info == NULL) {
+ g_error("Unable to find interface '" INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "'");
+ }
+ }
return;
}
@@ -108,6 +158,8 @@ indicator_messages_init (IndicatorMessages *self)
self->service = indicator_service_manager_new_version(INDICATOR_MESSAGES_DBUS_NAME, 1);
g_signal_connect(self->service, INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_change), self);
+ indicator = INDICATOR_OBJECT(self);
+
return;
}
@@ -140,54 +192,85 @@ indicator_messages_finalize (GObject *object)
/* Functions */
-/* Called everytime the attention changes in the service. */
+/* Signal off of the proxy */
static void
-attention_changed_cb (DBusGProxy * proxy, gboolean dot, gpointer userdata)
+proxy_signal (GDBusProxy * proxy, const gchar * sender, const gchar * signal, GVariant * params, gpointer user_data)
{
- if (dot) {
- indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages-new");
- } else {
- indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages");
- }
- return;
-}
+ gboolean prop = g_variant_get_boolean(g_variant_get_child_value(params, 0));
-/* Change the icon to whether it should be visible or not */
-static void
-icon_changed_cb (DBusGProxy * proxy, gboolean hidden, gpointer userdata)
-{
- if (hidden) {
- gtk_widget_hide(main_image);
+ if (g_strcmp0("AttentionChanged", signal) == 0) {
+ if (prop) {
+ indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages-new");
+ accessible_desc = _("New Messages");
+ } else {
+ indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages");
+ accessible_desc = _("Messages");
+ }
+ } else if (g_strcmp0("IconChanged", signal) == 0) {
+ if (prop) {
+ gtk_widget_hide(main_image);
+ } else {
+ gtk_widget_show(main_image);
+ }
} else {
- gtk_widget_show(main_image);
+ g_warning("Unknown signal %s", signal);
}
+
+ update_a11y_desc();
+
return;
}
/* Callback from getting the attention status from the service. */
static void
-attention_cb (DBusGProxy * proxy, gboolean dot, GError * error, gpointer userdata)
+attention_cb (GObject * object, GAsyncResult * ares, gpointer user_data)
{
+ GError * error = NULL;
+ GVariant * res = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), ares, &error);
+
if (error != NULL) {
g_warning("Unable to get attention status: %s", error->message);
g_error_free(error);
return;
}
- return attention_changed_cb(proxy, dot, userdata);
+ gboolean prop = g_variant_get_boolean(g_variant_get_child_value(res, 0));
+
+ if (prop) {
+ indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages-new");
+ accessible_desc = _("New Messages");
+ } else {
+ indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages");
+ accessible_desc = _("Messages");
+ }
+
+ update_a11y_desc();
+
+ return;
}
/* Change from getting the icon visibility from the service */
static void
-icon_cb (DBusGProxy * proxy, gboolean hidden, GError * error, gpointer userdata)
+icon_cb (GObject * object, GAsyncResult * ares, gpointer user_data)
{
+ GError * error = NULL;
+ GVariant * res = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), ares, &error);
+
if (error != NULL) {
g_warning("Unable to get icon visibility: %s", error->message);
g_error_free(error);
return;
}
- return icon_changed_cb(proxy, hidden, userdata);
+ gboolean prop = g_variant_get_boolean(g_variant_get_child_value(res, 0));
+
+ if (prop) {
+ gtk_widget_hide(main_image);
+ } else {
+ gtk_widget_show(main_image);
+ }
+
+ return;
}
static guint connection_drop_timeout = 0;
@@ -204,6 +287,43 @@ connection_drop_cb (gpointer user_data)
return FALSE;
}
+/* Proxy is setup now.. whoo! */
+static void
+proxy_ready_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
+{
+ GError * error = NULL;
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+ if (error != NULL) {
+ g_warning("Unable to get proxy of service: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ icon_proxy = proxy;
+
+ g_signal_connect(G_OBJECT(proxy), "g-signal", G_CALLBACK(proxy_signal), user_data);
+
+ g_dbus_proxy_call(icon_proxy,
+ "AttentionRequested",
+ NULL, /* params */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* timeout */
+ NULL, /* cancel */
+ attention_cb,
+ user_data);
+ g_dbus_proxy_call(icon_proxy,
+ "IconShown",
+ NULL, /* params */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* timeout */
+ NULL, /* cancel */
+ icon_cb,
+ user_data);
+
+ return;
+}
+
/* Sets up all the icon information in the proxy. */
static void
connection_change (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
@@ -220,51 +340,46 @@ connection_change (IndicatorServiceManager * sm, gboolean connected, gpointer us
return;
}
- DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- if (connection == NULL) {
- g_warning("Unable to get session bus");
- return;
- }
-
if (icon_proxy == NULL) {
- icon_proxy = dbus_g_proxy_new_for_name(connection,
- INDICATOR_MESSAGES_DBUS_NAME,
- INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT,
- INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE);
- if (icon_proxy == NULL) {
- g_warning("Unable to get messages service interface.");
- return;
- }
-
- dbus_g_proxy_add_signal(icon_proxy, "AttentionChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(icon_proxy,
- "AttentionChanged",
- G_CALLBACK(attention_changed_cb),
- NULL,
- NULL);
-
- dbus_g_proxy_add_signal(icon_proxy, "IconChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal(icon_proxy,
- "IconChanged",
- G_CALLBACK(icon_changed_cb),
- NULL,
- NULL);
+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ bus_interface_info,
+ INDICATOR_MESSAGES_DBUS_NAME,
+ INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT,
+ INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE,
+ NULL, /* cancel */
+ proxy_ready_cb,
+ sm);
+ } else {
+ g_dbus_proxy_call(icon_proxy,
+ "AttentionRequested",
+ NULL, /* params */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* timeout */
+ NULL, /* cancel */
+ attention_cb,
+ sm);
+ g_dbus_proxy_call(icon_proxy,
+ "IconShown",
+ NULL, /* params */
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, /* timeout */
+ NULL, /* cancel */
+ icon_cb,
+ sm);
}
- org_ayatana_indicator_messages_service_attention_requested_async(icon_proxy, attention_cb, NULL);
- org_ayatana_indicator_messages_service_icon_shown_async(icon_proxy, icon_cb, NULL);
-
return;
}
/* Sets the icon when it changes. */
static void
-application_icon_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, gpointer user_data)
+application_icon_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, gpointer user_data)
{
if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_ICON)) {
/* Set the main icon */
if (GTK_IS_IMAGE(user_data)) {
- gtk_image_set_from_icon_name(GTK_IMAGE(user_data), g_value_get_string(value), GTK_ICON_SIZE_MENU);
+ gtk_image_set_from_icon_name(GTK_IMAGE(user_data), g_variant_get_string(value, NULL), GTK_ICON_SIZE_MENU);
}
}
@@ -273,24 +388,150 @@ application_icon_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value,
/* Sets the label when it changes. */
static void
-application_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, gpointer user_data)
+application_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * 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));
+ gtk_label_set_text(GTK_LABEL(user_data), g_variant_get_string(value, NULL));
}
}
+ if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_RUNNING)) {
+ /* TODO: should hide/show the triangle live if the menu was open.
+ In practice, this is rarely needed. */
+ }
+
return;
}
+/* Draws a triangle on the left, using fg[STATE_TYPE] color. */
+static gboolean
+application_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+ GtkAllocation allocation;
+ GtkStyle *style;
+ cairo_t *cr;
+ int x, y, arrow_width, arrow_height;
+
+ if (!GTK_IS_WIDGET (widget)) return FALSE;
+ if (!DBUSMENU_IS_MENUITEM (data)) return FALSE;
+
+ /* render the triangle indicator only if the application is running */
+ if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data), APPLICATION_MENUITEM_PROP_RUNNING))
+ return FALSE;;
+
+ /* get style */
+ style = gtk_widget_get_style (widget);
+
+ /* set arrow position / dimensions */
+ arrow_width = 5; /* the pixel-based reference triangle is 5x9 */
+ arrow_height = 9;
+ gtk_widget_get_allocation (widget, &allocation);
+ x = allocation.x;
+ y = allocation.y + allocation.height/2.0 - (double)arrow_height/2.0;
+
+ /* initialize cairo drawing area */
+ cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget));
+
+ /* set line width */
+ cairo_set_line_width (cr, 1.0);
+
+ /* cairo drawing code */
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x, y + arrow_height);
+ cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0);
+ cairo_close_path (cr);
+ cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
+ style->fg[gtk_widget_get_state(widget)].green/65535.0,
+ style->fg[gtk_widget_get_state(widget)].blue/65535.0);
+ cairo_fill (cr);
+
+ /* remember to destroy cairo context to avoid leaks */
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+/* Custom function to draw rounded rectangle with max radius */
+static void
+custom_cairo_rounded_rectangle (cairo_t *cr,
+ double x, double y, double w, double h)
+{
+ double radius = MIN (w/2.0, h/2.0);
+
+ cairo_move_to (cr, x+radius, y);
+ cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.5, M_PI*2);
+ cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI*0.5);
+ cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.5, M_PI);
+ cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5);
+}
+
+/* Draws a rounded rectangle with text inside. */
+static gboolean
+numbers_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+ GtkAllocation allocation;
+ GtkStyle *style;
+ cairo_t *cr;
+ double x, y, w, h;
+ PangoLayout * layout;
+ gint font_size = RIGHT_LABEL_FONT_SIZE;
+
+ if (!GTK_IS_WIDGET (widget)) return FALSE;
+
+ /* get style */
+ style = gtk_widget_get_style (widget);
+
+ /* set arrow position / dimensions */
+ gtk_widget_get_allocation (widget, &allocation);
+ w = allocation.width;
+ h = allocation.height;
+ x = allocation.x;
+ y = allocation.y;
+
+ layout = gtk_label_get_layout (GTK_LABEL(widget));
+
+ /* This does not work, don't ask me why but font_size is 0.
+ * I wanted to use a dynamic font size to adjust the padding on left/right edges
+ * of the rounded rectangle. Andrea Cimitan */
+ /* const PangoFontDescription * font_description = pango_layout_get_font_description (layout);
+ font_size = pango_font_description_get_size (font_description); */
+
+ /* initialize cairo drawing area */
+ cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget));
+
+ /* set line width */
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ /* cairo drawing code */
+ custom_cairo_rounded_rectangle (cr, x - font_size/2.0, y, w + font_size, h);
+
+ cairo_set_source_rgba (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
+ style->fg[gtk_widget_get_state(widget)].green/65535.0,
+ style->fg[gtk_widget_get_state(widget)].blue/65535.0, 0.5);
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_layout_path (cr, layout);
+ cairo_fill (cr);
+
+ /* remember to destroy cairo context to avoid leaks */
+ cairo_destroy (cr);
+
+ return TRUE;
+}
+
/* Builds a menu item representing a running application in the
messaging menu */
static gboolean
-new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
+new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
{
+ g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_NAME));
+
GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_image_menu_item_new());
+ gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(gmi), TRUE);
gint padding = 4;
gtk_widget_style_get(GTK_WIDGET(gmi), "horizontal-padding", &padding, NULL);
@@ -302,9 +543,12 @@ new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu
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_set_size_request(icon, width
+ + 5 /* ref triangle is 5x9 pixels */
+ + 2 /* padding */,
+ height);
+ gtk_misc_set_alignment(GTK_MISC(icon), 1.0 /* right aligned */, 0.5);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gmi), icon);
gtk_widget_show(icon);
/* Application name in a label */
@@ -317,25 +561,17 @@ new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbu
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);
g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(application_icon_change_cb), icon);
+ g_signal_connect_after(G_OBJECT (gmi), "expose_event", G_CALLBACK (application_triangle_draw_cb), newitem);
return TRUE;
}
-
typedef struct _indicator_item_t indicator_item_t;
struct _indicator_item_t {
GtkWidget * icon;
@@ -346,14 +582,14 @@ struct _indicator_item_t {
/* Whenever we have a property change on a DbusmenuMenuitem
we need to be responsive to that. */
static void
-indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, indicator_item_t * mi_data)
+indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, indicator_item_t * mi_data)
{
if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_LABEL)) {
/* Set the main label */
- gtk_label_set_text(GTK_LABEL(mi_data->label), g_value_get_string(value));
+ gtk_label_set_text(GTK_LABEL(mi_data->label), g_variant_get_string(value, NULL));
} else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_RIGHT)) {
/* Set the right label */
- gtk_label_set_text(GTK_LABEL(mi_data->right), g_value_get_string(value));
+ gtk_label_set_text(GTK_LABEL(mi_data->right), g_variant_get_string(value, NULL));
} else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_ICON)) {
/* We don't use the value here, which is probably less efficient,
but it's easier to use the easy function. And since th value
@@ -383,6 +619,10 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, i
if (resized_pixbuf != pixbuf) {
g_object_unref(resized_pixbuf);
}
+
+ gtk_widget_show(mi_data->icon);
+ } else {
+ gtk_widget_hide(mi_data->icon);
}
}
@@ -394,7 +634,7 @@ indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, i
shifting over and putting the icon in with some right
side text that'll be determined by the service. */
static gboolean
-new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
+new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
{
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
@@ -405,6 +645,7 @@ new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm
GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
gint padding = 4;
+ gint font_size = RIGHT_LABEL_FONT_SIZE;
gtk_widget_style_get(GTK_WIDGET(gmi), "horizontal-padding", &padding, NULL);
GtkWidget * hbox = gtk_hbox_new(FALSE, 0);
@@ -443,7 +684,10 @@ new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm
}
gtk_misc_set_alignment(GTK_MISC(mi_data->icon), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), mi_data->icon, FALSE, FALSE, padding);
- gtk_widget_show(mi_data->icon);
+
+ if (pixbuf != NULL) {
+ gtk_widget_show(mi_data->icon);
+ }
/* Label, probably a username, chat room or mailbox name */
mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_LABEL));
@@ -455,8 +699,12 @@ new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm
item. */
mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT));
gtk_size_group_add_widget(indicator_right_group, mi_data->right);
+ /* install extra decoration overlay */
+ g_signal_connect (G_OBJECT (mi_data->right), "expose_event",
+ G_CALLBACK (numbers_draw_cb), NULL);
+
gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, padding);
+ gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, padding + font_size/2.0);
gtk_widget_show(mi_data->right);
gtk_container_add(GTK_CONTAINER(gmi), hbox);
@@ -495,3 +743,9 @@ get_menu (IndicatorObject * io)
return GTK_MENU(menu);
}
+/* Returns the accessible description of the indicator */
+static const gchar *
+get_accessible_desc (IndicatorObject * io)
+{
+ return accessible_desc;
+}