From cd6da41abeb0ad5dd9bf15158efcb5fda1ee8870 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 25 May 2012 18:17:46 +0200 Subject: Port to gmenu, act II - the indicator object Ports the indicator object itself to listen to exported gactions and gmenumodels. The menu creation itself is outsourced to a new dependency: menu-factory-gtk. --- src/indicator-messages.c | 385 ++++------------------------------------------- 1 file changed, 31 insertions(+), 354 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 32f97f7..b6707f5 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -29,14 +29,13 @@ with this program. If not, see . #include #include -#include -#include - #include #include #include #include +#include + #include "dbus-data.h" #include "gen-messages-service.xml.h" @@ -58,6 +57,8 @@ struct _IndicatorMessagesClass { struct _IndicatorMessages { IndicatorObject parent; IndicatorServiceManager * service; + GActionGroup *actions; + GMenuModel *menu; }; GType indicator_messages_get_type (void); @@ -155,6 +156,9 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) static void indicator_messages_init (IndicatorMessages *self) { + GDBusConnection *bus; + GError *error = NULL; + /* Default values */ self->service = NULL; @@ -162,9 +166,24 @@ 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); + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (!bus) { + g_warning ("error connecting to the session bus: %s", error->message); + g_error_free (error); + return; + } + + self->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, + INDICATOR_MESSAGES_DBUS_NAME, + INDICATOR_MESSAGES_DBUS_OBJECT)); + + self->menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, + INDICATOR_MESSAGES_DBUS_NAME, + INDICATOR_MESSAGES_DBUS_OBJECT)); + indicator = INDICATOR_OBJECT(self); - return; + g_object_unref (bus); } /* Unref stuff */ @@ -179,6 +198,9 @@ indicator_messages_dispose (GObject *object) self->service = NULL; } + g_clear_object (&self->actions); + g_clear_object (&self->menu); + G_OBJECT_CLASS (indicator_messages_parent_class)->dispose (object); return; } @@ -376,206 +398,6 @@ connection_change (IndicatorServiceManager * sm, gboolean connected, gpointer us return; } -/* Sets the icon when it changes. */ -static void -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_variant_get_string(value, NULL), GTK_ICON_SIZE_MENU); - } - } - - return; -} - -/* Sets the label when it changes. */ -static void -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_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, cairo_t *cr, gpointer data) -{ - GtkAllocation allocation; - GtkStyle *style; - 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 = 0; - y = allocation.height/2.0 - (double)arrow_height/2.0; - - cairo_save (cr); - - /* 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); - - cairo_restore (cr); - - return FALSE; -} - -static gint -gtk_widget_get_font_size (GtkWidget *widget) -{ - const PangoFontDescription *font; - - font = gtk_style_context_get_font (gtk_widget_get_style_context (widget), - gtk_widget_get_state_flags (widget)); - - return pango_font_description_get_size (font) / PANGO_SCALE; -} - -/* 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 = 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, cairo_t *cr, gpointer data) -{ - GtkAllocation allocation; - GtkStyle *style; - double x, y, w, h; - PangoLayout * layout; - PangoRectangle layout_extents; - gint font_size = gtk_widget_get_font_size (widget); - gboolean is_lozenge = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "is-lozenge")); - - if (!GTK_IS_WIDGET (widget)) return FALSE; - - /* let the label handle the drawing if it's not a lozenge */ - if (!is_lozenge) - return FALSE; - - /* get style */ - style = gtk_widget_get_style (widget); - - /* set arrow position / dimensions */ - gtk_widget_get_allocation (widget, &allocation); - x = 0; - y = 0; - w = allocation.width; - h = allocation.height; - - layout = gtk_label_get_layout (GTK_LABEL(widget)); - pango_layout_get_extents (layout, NULL, &layout_extents); - pango_extents_to_pixels (&layout_extents, NULL); - - if (layout_extents.width == 0) - return TRUE; - - cairo_save (cr); - - /* 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); - - x += (allocation.width - layout_extents.width) / 2.0; - y += (allocation.height - layout_extents.height) / 2.0; - cairo_move_to (cr, floor (x), floor (y)); - pango_cairo_layout_path (cr, layout); - cairo_fill (cr); - - cairo_restore (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, gpointer user_data) -{ - g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_NAME)); - - GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - - gint padding = 4; - gtk_widget_style_get(GTK_WIDGET(gmi), "toggle-spacing", &padding, NULL); - - GtkWidget * hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding); - - GtkWidget * icon = gtk_image_new_from_icon_name(dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_ICON), GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment(GTK_MISC(icon), 1.0 /* right aligned */, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); - - /* Application name in a label */ - GtkWidget * label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_NAME)); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); - - gtk_container_add(GTK_CONTAINER(gmi), hbox); - gtk_widget_show_all (GTK_WIDGET (gmi)); - - /* 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), "draw", G_CALLBACK (application_triangle_draw_cb), newitem); - - return TRUE; -} - typedef struct _indicator_item_t indicator_item_t; struct _indicator_item_t { GtkWidget * icon; @@ -583,151 +405,6 @@ struct _indicator_item_t { GtkWidget * right; }; -/* 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, 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_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_variant_get_string(value, NULL)); - } else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE)) { - g_object_set_data (G_OBJECT (mi_data->right), "is-lozenge", GINT_TO_POINTER (TRUE)); - gtk_widget_queue_draw (mi_data->right); - } 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 - is already cached, shouldn't be a big deal really. */ - GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(mi, INDICATOR_MENUITEM_PROP_ICON); - if (pixbuf != NULL) { - /* If we've got a pixbuf we need to make sure it's of a reasonable - size to fit in the menu. If not, rescale it. */ - GdkPixbuf * resized_pixbuf; - gint width, height; - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (gdk_pixbuf_get_width(pixbuf) > width || - gdk_pixbuf_get_height(pixbuf) > height) { - g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height); - resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, - width, - height, - GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - } else { - g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); - resized_pixbuf = pixbuf; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf); - - g_object_unref(resized_pixbuf); - - gtk_widget_show(mi_data->icon); - } else { - gtk_widget_hide(mi_data->icon); - } - } - - return; -} - -/* We have a small little menuitem type that handles all - of the fun stuff for indicators. Mostly this is the - 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, gpointer user_data) -{ - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - /* Note: not checking parent, it's reasonable for it to be NULL */ - - indicator_item_t * mi_data = g_new0(indicator_item_t, 1); - - GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - - gint padding = 4; - gint font_size = gtk_widget_get_font_size (GTK_WIDGET (gmi)); - gtk_widget_style_get(GTK_WIDGET(gmi), "toggle-spacing", &padding, NULL); - - GtkWidget * hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding); - - /* Icon, probably someone's face or avatar on an IM */ - mi_data->icon = gtk_image_new(); - - /* Set the minimum size, we always want it to take space */ - gint width, height; - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - gtk_widget_set_size_request(GTK_WIDGET (gmi), -1, height + 4); - - gtk_widget_set_margin_left (hbox, width + padding); - - GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, INDICATOR_MENUITEM_PROP_ICON); - if (pixbuf != NULL) { - /* If we've got a pixbuf we need to make sure it's of a reasonable - size to fit in the menu. If not, rescale it. */ - GdkPixbuf * resized_pixbuf; - if (gdk_pixbuf_get_width(pixbuf) > width || - gdk_pixbuf_get_height(pixbuf) > height) { - g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height); - resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, - width, - height, - GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - } else { - g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); - resized_pixbuf = pixbuf; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf); - - g_object_unref(resized_pixbuf); - } - 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, 0); - - 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)); - gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0); - gtk_widget_show(mi_data->label); - - /* Usually either the time or the count on the individual - item. */ - mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT)); - g_object_set_data (G_OBJECT (mi_data->right), - "is-lozenge", - GINT_TO_POINTER (dbusmenu_menuitem_property_get_bool (newitem, INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE))); - /* install extra decoration overlay */ - g_signal_connect (G_OBJECT (mi_data->right), "draw", - 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 + font_size/2.0); - gtk_label_set_width_chars (GTK_LABEL (mi_data->right), 2); - gtk_style_context_add_class (gtk_widget_get_style_context (mi_data->right), - "accelerator"); - gtk_widget_show(mi_data->right); - - gtk_container_add(GTK_CONTAINER(gmi), hbox); - gtk_widget_show(hbox); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); - - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data); - g_object_weak_ref(G_OBJECT(newitem), (GWeakNotify)g_free, mi_data); - - return TRUE; -} - /* Builds the main image icon using the libindicator helper. */ static GtkImage * get_icon (IndicatorObject * io) @@ -742,13 +419,13 @@ get_icon (IndicatorObject * io) static GtkMenu * get_menu (IndicatorObject * io) { - DbusmenuGtkMenu * menu = dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT); - DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu); + IndicatorMessages *self = INDICATOR_MESSAGES (io); + GtkMenu *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); + menu = menu_factory_gtk_new_menu (self->menu, self->actions); + gtk_widget_show_all (GTK_WIDGET (menu)); - return GTK_MENU(menu); + return menu; } /* Returns the accessible description of the indicator */ -- cgit v1.2.3 From 1caa3be43ec40c7fb1bbb37a585555fe2526dc57 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 15:33:13 +0200 Subject: Remove dependency on menu-factory libindicator now has GMenuModel support (unreleased), so indicator-messages doesn't need to create gtk menus anymore. --- src/indicator-messages.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index b6707f5..eb0b1fb 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -34,8 +34,6 @@ with this program. If not, see . #include #include -#include - #include "dbus-data.h" #include "gen-messages-service.xml.h" @@ -81,7 +79,8 @@ static void indicator_messages_init (IndicatorMessages *self); 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 GMenuModel * get_menu_model (IndicatorObject * io); +static GActionGroup * get_actions (IndicatorObject * io); static void indicator_messages_middle_click (IndicatorObject * io, IndicatorObjectEntry * entry, guint time, gpointer data); @@ -126,7 +125,8 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); io_class->get_image = get_icon; - io_class->get_menu = get_menu; + io_class->get_menu_model = get_menu_model; + io_class->get_actions = get_actions; io_class->get_accessible_desc = get_accessible_desc; io_class->get_name_hint = get_name_hint; io_class->secondary_activate = indicator_messages_middle_click; @@ -416,16 +416,18 @@ get_icon (IndicatorObject * io) } /* Builds the menu for the indicator */ -static GtkMenu * -get_menu (IndicatorObject * io) +static GMenuModel * +get_menu_model (IndicatorObject * io) { IndicatorMessages *self = INDICATOR_MESSAGES (io); - GtkMenu *menu; - - menu = menu_factory_gtk_new_menu (self->menu, self->actions); - gtk_widget_show_all (GTK_WIDGET (menu)); + return self->menu; +} - return menu; +static GActionGroup * +get_actions (IndicatorObject *io) +{ + IndicatorMessages *self = INDICATOR_MESSAGES (io); + return self->actions; } /* Returns the accessible description of the indicator */ -- cgit v1.2.3 From 315c058bcc7c152615cf35f11c0f29d8ee9ec01b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 21:08:03 +0200 Subject: indicator-messages.c: remove messages-service proxy It wasn't used anymore, all menu-related things are communicated via gmenu now. Regression: accessible description --- src/indicator-messages.c | 267 ----------------------------------------------- 1 file changed, 267 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index eb0b1fb..70efd52 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -49,7 +49,6 @@ typedef struct _IndicatorMessagesClass IndicatorMessagesClass; struct _IndicatorMessagesClass { IndicatorObjectClass parent_class; - void (*update_a11y_desc) (IndicatorServiceManager * service, gpointer * user_data); }; struct _IndicatorMessages { @@ -66,10 +65,6 @@ INDICATOR_SET_VERSION INDICATOR_SET_TYPE(INDICATOR_MESSAGES_TYPE) /* Globals */ -static GtkWidget * main_image = NULL; -static GDBusProxy * icon_proxy = NULL; -static GDBusNodeInfo * bus_node_info = NULL; -static GDBusInterfaceInfo * bus_interface_info = NULL; static const gchar * accessible_desc = NULL; static IndicatorObject * indicator = NULL; @@ -78,41 +73,13 @@ static void indicator_messages_class_init (IndicatorMessagesClass *klass); static void indicator_messages_init (IndicatorMessages *self); static void indicator_messages_dispose (GObject *object); static void indicator_messages_finalize (GObject *object); -static GtkImage * get_icon (IndicatorObject * io); static GMenuModel * get_menu_model (IndicatorObject * io); static GActionGroup * get_actions (IndicatorObject * io); -static void indicator_messages_middle_click (IndicatorObject * io, - IndicatorObjectEntry * entry, - guint time, gpointer data); static const gchar * get_accessible_desc (IndicatorObject * io); static const gchar * get_name_hint (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) @@ -124,32 +91,10 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - io_class->get_image = get_icon; io_class->get_menu_model = get_menu_model; io_class->get_actions = get_actions; io_class->get_accessible_desc = get_accessible_desc; io_class->get_name_hint = get_name_hint; - io_class->secondary_activate = indicator_messages_middle_click; - - 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; } /* Build up our per-instance variables */ @@ -164,7 +109,6 @@ indicator_messages_init (IndicatorMessages *self) /* Complex stuff */ 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); bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (!bus) { @@ -218,186 +162,6 @@ indicator_messages_finalize (GObject *object) /* Functions */ -/* Signal off of the proxy */ -static void -proxy_signal (GDBusProxy * proxy, const gchar * sender, const gchar * signal, GVariant * params, gpointer user_data) -{ - gboolean prop = g_variant_get_boolean(g_variant_get_child_value(params, 0)); - - 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 { - g_warning("Unknown signal %s", signal); - } - - update_a11y_desc(); - - return; -} - -/* Callback from getting the attention status from the service. */ -static void -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; - } - - 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 (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; - } - - 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; - -/* Resets the icon to not having messages if we can't get a good - answer on it from the service. */ -static gboolean -connection_drop_cb (gpointer user_data) -{ - if (main_image != NULL) { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages"); - } - connection_drop_timeout = 0; - 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) -{ - if (connection_drop_timeout != 0) { - g_source_remove(connection_drop_timeout); - connection_drop_timeout = 0; - } - - if (!connected) { - /* Ensure that we're not saying there are messages - when we don't have a connection. */ - connection_drop_timeout = g_timeout_add(400, connection_drop_cb, NULL); - return; - } - - if (icon_proxy == 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); - } - - return; -} - typedef struct _indicator_item_t indicator_item_t; struct _indicator_item_t { GtkWidget * icon; @@ -405,16 +169,6 @@ struct _indicator_item_t { GtkWidget * right; }; -/* Builds the main image icon using the libindicator helper. */ -static GtkImage * -get_icon (IndicatorObject * io) -{ - main_image = GTK_WIDGET(indicator_image_helper("indicator-messages")); - gtk_widget_show(main_image); - - return GTK_IMAGE(main_image); -} - /* Builds the menu for the indicator */ static GMenuModel * get_menu_model (IndicatorObject * io) @@ -443,24 +197,3 @@ get_name_hint (IndicatorObject *io) { return PACKAGE; } - -/* Hide the notifications on middle-click over the indicator-messages */ -static void -indicator_messages_middle_click (IndicatorObject * io, IndicatorObjectEntry * entry, - guint time, gpointer data) -{ - if (icon_proxy == NULL) { - return; - } - - g_dbus_proxy_call(icon_proxy, - "ClearAttention", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - NULL, - NULL); - - return; -} -- cgit v1.2.3 From 193886f467b636a91d546656017de3fd0fa62677 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 21:42:23 +0200 Subject: Use gdbus-codegen also for the server side messages service --- src/indicator-messages.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 70efd52..6278461 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -35,7 +35,6 @@ with this program. If not, see . #include #include "dbus-data.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)) -- cgit v1.2.3 From 2b1abaeccb3b07f609ceee8bd34f60eea78d9bbc Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 16 Aug 2012 19:59:39 +0200 Subject: Use the old libindicator API indicator-messages is the only indicator that communicates with its service through GMenuModel. This patch keeps the GMenuModel stuff, but creates the GtkMenu in the plugin instead of relying on unity-panel-service. --- src/indicator-messages.c | 103 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 13 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 6278461..17e8677 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -54,7 +54,9 @@ struct _IndicatorMessages { IndicatorObject parent; IndicatorServiceManager * service; GActionGroup *actions; + GMenu *menu_wrapper; GMenuModel *menu; + GtkWidget *image; }; GType indicator_messages_get_type (void); @@ -72,10 +74,17 @@ static void indicator_messages_class_init (IndicatorMessagesClass *klass); static void indicator_messages_init (IndicatorMessages *self); static void indicator_messages_dispose (GObject *object); static void indicator_messages_finalize (GObject *object); -static GMenuModel * get_menu_model (IndicatorObject * io); -static GActionGroup * get_actions (IndicatorObject * io); +static GtkImage * get_image (IndicatorObject * io); +static GtkMenu * get_menu (IndicatorObject * io); static const gchar * get_accessible_desc (IndicatorObject * io); static const gchar * get_name_hint (IndicatorObject * io); +static void update_icon (IndicatorMessages * self); +static void update_menu (IndicatorMessages *self); +static void menu_items_changed (GMenuModel *menu, + gint position, + gint removed, + gint added, + gpointer user_data); G_DEFINE_TYPE (IndicatorMessages, indicator_messages, INDICATOR_OBJECT_TYPE); @@ -90,8 +99,8 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - io_class->get_menu_model = get_menu_model; - io_class->get_actions = get_actions; + io_class->get_image = get_image; + io_class->get_menu = get_menu; io_class->get_accessible_desc = get_accessible_desc; io_class->get_name_hint = get_name_hint; } @@ -124,6 +133,15 @@ indicator_messages_init (IndicatorMessages *self) INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT)); + g_signal_connect (self->menu, "items-changed", G_CALLBACK (menu_items_changed), self); + + self->image = g_object_ref_sink (gtk_image_new ()); + gtk_widget_show (self->image); + update_icon (self); + + self->menu_wrapper = g_menu_new (); + update_menu (self); + indicator = INDICATOR_OBJECT(self); g_object_unref (bus); @@ -141,8 +159,10 @@ indicator_messages_dispose (GObject *object) self->service = NULL; } + g_clear_object (&self->menu_wrapper); g_clear_object (&self->actions); g_clear_object (&self->menu); + g_clear_object (&self->image); G_OBJECT_CLASS (indicator_messages_parent_class)->dispose (object); return; @@ -168,31 +188,88 @@ struct _indicator_item_t { GtkWidget * right; }; -/* Builds the menu for the indicator */ -static GMenuModel * -get_menu_model (IndicatorObject * io) +static GtkImage * +get_image (IndicatorObject * io) { IndicatorMessages *self = INDICATOR_MESSAGES (io); - return self->menu; + + return GTK_IMAGE (self->image); } -static GActionGroup * -get_actions (IndicatorObject *io) +static GtkMenu * +get_menu (IndicatorObject * io) { IndicatorMessages *self = INDICATOR_MESSAGES (io); - return self->actions; + GtkWidget *menu; + + menu = gtk_menu_new_from_model (G_MENU_MODEL (self->menu_wrapper)); + gtk_widget_insert_action_group (menu, get_name_hint (io), self->actions); + + return GTK_MENU (menu); } -/* Returns the accessible description of the indicator */ static const gchar * get_accessible_desc (IndicatorObject * io) { return accessible_desc; } -/* Returns the name hint of the indicator */ static const gchar * get_name_hint (IndicatorObject *io) { return PACKAGE; } + +static void +update_icon (IndicatorMessages * self) +{ + const gchar *icon_name; + + if (g_menu_model_get_n_items (self->menu) == 0) + return; + + g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, + "&s", &icon_name); + + gtk_image_set_from_icon_name (GTK_IMAGE (self->image), icon_name, GTK_ICON_SIZE_MENU); +} + +static void +update_menu (IndicatorMessages *self) +{ + GMenuModel *popup; + GMenuItem *item; + + if (g_menu_model_get_n_items (self->menu) == 0) + return; + + popup = g_menu_model_get_item_link (self->menu, 0, G_MENU_LINK_SUBMENU); + if (popup == NULL) + return; + + if (g_menu_model_get_n_items (G_MENU_MODEL (self->menu_wrapper)) == 1) + g_menu_remove (self->menu_wrapper, 0); + + item = g_menu_item_new_section (NULL, popup); + g_menu_item_set_attribute (item, "action-namespace", + "s", get_name_hint (INDICATOR_OBJECT (self))); + g_menu_append_item (self->menu_wrapper, item); + + g_object_unref (item); + g_object_unref (popup); +} + +static void +menu_items_changed (GMenuModel *menu, + gint position, + gint removed, + gint added, + gpointer user_data) +{ + IndicatorMessages *self = user_data; + + if (position == 0) { + update_icon (self); + update_menu (self); + } +} -- cgit v1.2.3 From ceebc0610fc101f25f64e4c45d08a1bee4fdfdd0 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 16 Aug 2012 20:02:51 +0200 Subject: panel plugin: remove unused global variables and struct --- src/indicator-messages.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 17e8677..8755a02 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -65,10 +65,6 @@ GType indicator_messages_get_type (void); INDICATOR_SET_VERSION INDICATOR_SET_TYPE(INDICATOR_MESSAGES_TYPE) -/* Globals */ -static const gchar * accessible_desc = NULL; -static IndicatorObject * indicator = NULL; - /* Prototypes */ static void indicator_messages_class_init (IndicatorMessagesClass *klass); static void indicator_messages_init (IndicatorMessages *self); @@ -142,8 +138,6 @@ indicator_messages_init (IndicatorMessages *self) self->menu_wrapper = g_menu_new (); update_menu (self); - indicator = INDICATOR_OBJECT(self); - g_object_unref (bus); } @@ -181,13 +175,6 @@ indicator_messages_finalize (GObject *object) /* Functions */ -typedef struct _indicator_item_t indicator_item_t; -struct _indicator_item_t { - GtkWidget * icon; - GtkWidget * label; - GtkWidget * right; -}; - static GtkImage * get_image (IndicatorObject * io) { @@ -211,7 +198,7 @@ get_menu (IndicatorObject * io) static const gchar * get_accessible_desc (IndicatorObject * io) { - return accessible_desc; + return NULL; } static const gchar * -- cgit v1.2.3 From 2c2d155860b16329d6f2c697b64cbe6f2ad639e2 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 16 Aug 2012 20:35:07 +0200 Subject: Set accessible description (statically to "Messages" for now) --- src/indicator-messages.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 8755a02..14833fd 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -57,6 +57,7 @@ struct _IndicatorMessages { GMenu *menu_wrapper; GMenuModel *menu; GtkWidget *image; + gchar *accessible_desc; }; GType indicator_messages_get_type (void); @@ -74,7 +75,7 @@ static GtkImage * get_image (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); static const gchar * get_accessible_desc (IndicatorObject * io); static const gchar * get_name_hint (IndicatorObject * io); -static void update_icon (IndicatorMessages * self); +static void update_root_item (IndicatorMessages * self); static void update_menu (IndicatorMessages *self); static void menu_items_changed (GMenuModel *menu, gint position, @@ -133,7 +134,7 @@ indicator_messages_init (IndicatorMessages *self) self->image = g_object_ref_sink (gtk_image_new ()); gtk_widget_show (self->image); - update_icon (self); + update_root_item (self); self->menu_wrapper = g_menu_new (); update_menu (self); @@ -166,6 +167,9 @@ indicator_messages_dispose (GObject *object) static void indicator_messages_finalize (GObject *object) { + IndicatorMessages *self = INDICATOR_MESSAGES (object); + + g_free (self->accessible_desc); G_OBJECT_CLASS (indicator_messages_parent_class)->finalize (object); return; @@ -198,7 +202,8 @@ get_menu (IndicatorObject * io) static const gchar * get_accessible_desc (IndicatorObject * io) { - return NULL; + IndicatorMessages *self = INDICATOR_MESSAGES (io); + return self->accessible_desc; } static const gchar * @@ -208,7 +213,18 @@ get_name_hint (IndicatorObject *io) } static void -update_icon (IndicatorMessages * self) +indicator_messages_accessible_desc_updated (IndicatorMessages *self) +{ + GList *entries; + + entries = indicator_object_get_entries (INDICATOR_OBJECT (self)); + g_return_if_fail (entries != NULL); + + g_signal_emit_by_name (self, INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, entries->data); +} + +static void +update_root_item (IndicatorMessages * self) { const gchar *icon_name; @@ -218,6 +234,12 @@ update_icon (IndicatorMessages * self) g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "&s", &icon_name); + g_free (self->accessible_desc); + + g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ACCESSIBLE_DESCRIPTION, + "s", &self->accessible_desc); + indicator_messages_accessible_desc_updated (self); + gtk_image_set_from_icon_name (GTK_IMAGE (self->image), icon_name, GTK_ICON_SIZE_MENU); } @@ -256,7 +278,7 @@ menu_items_changed (GMenuModel *menu, IndicatorMessages *self = user_data; if (position == 0) { - update_icon (self); + update_root_item (self); update_menu (self); } } -- cgit v1.2.3 From 5b852d2f1fd35640ce94982c8078ce1603ed12a2 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 19 Aug 2012 16:24:42 -0500 Subject: in indicator-messages's dispose(), use g_clear_object() --- src/indicator-messages.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 14833fd..12109ca 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -149,11 +149,7 @@ indicator_messages_dispose (GObject *object) IndicatorMessages * self = INDICATOR_MESSAGES(object); g_return_if_fail(self != NULL); - if (self->service != NULL) { - g_object_unref(self->service); - self->service = NULL; - } - + g_clear_object (&self->service); g_clear_object (&self->menu_wrapper); g_clear_object (&self->actions); g_clear_object (&self->menu); -- cgit v1.2.3 From 666abf25d2fe9c71577040b2ef9cdba825c77668 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 19 Aug 2012 19:22:09 -0500 Subject: in indicator-messages' indicator_messages_accessible_desc_updated(), don't leak the entries GList --- src/indicator-messages.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 12109ca..162fd4d 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -217,6 +217,8 @@ indicator_messages_accessible_desc_updated (IndicatorMessages *self) g_return_if_fail (entries != NULL); g_signal_emit_by_name (self, INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, entries->data); + + g_list_free (entries); } static void -- cgit v1.2.3 From 004314963a36bb48473ae58eccc9f5532225ab9b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 20 Aug 2012 21:32:33 +0200 Subject: Use a custom menu item for application items This introduces ImAppMenuItem: a menu item which shows a small triangle next to an application's name if the associated app is running. The running state is communicated to the menu by giving the "launch" action a boolean state. This depends on a patch to gtk which creates custom menu items from gtk_menu_new_from_model when the x-canonical-type attribute is set on a menu item in the model. --- src/indicator-messages.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 14833fd..67a28e9 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -36,6 +36,8 @@ with this program. If not, see . #include "dbus-data.h" +#include "im-app-menu-item.h" + #define INDICATOR_MESSAGES_TYPE (indicator_messages_get_type ()) #define INDICATOR_MESSAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_MESSAGES_TYPE, IndicatorMessages)) #define INDICATOR_MESSAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_MESSAGES_TYPE, IndicatorMessagesClass)) @@ -140,6 +142,10 @@ indicator_messages_init (IndicatorMessages *self) update_menu (self); g_object_unref (bus); + + /* make sure custom menu item types are registered (so that + * gtk_model_new_from_menu can pick them up */ + im_app_menu_item_get_type (); } /* Unref stuff */ -- cgit v1.2.3 From 91eb0b1a17c5bc9d0087fe807f373d1b8a8eb87b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 21 Aug 2012 01:41:26 +0200 Subject: Use a custom menu item for message source menu items --- src/indicator-messages.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 4e8701a..d898ad6 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -37,6 +37,7 @@ with this program. If not, see . #include "dbus-data.h" #include "im-app-menu-item.h" +#include "im-source-menu-item.h" #define INDICATOR_MESSAGES_TYPE (indicator_messages_get_type ()) #define INDICATOR_MESSAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_MESSAGES_TYPE, IndicatorMessages)) @@ -146,6 +147,7 @@ indicator_messages_init (IndicatorMessages *self) /* make sure custom menu item types are registered (so that * gtk_model_new_from_menu can pick them up */ im_app_menu_item_get_type (); + im_source_menu_item_get_type (); } /* Unref stuff */ -- cgit v1.2.3 From 7d036b65aac90b646eb7845cfc8e229464f372f0 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 21 Aug 2012 11:40:47 +0200 Subject: Show icons in application and source menu items Everthing goes through GIcon now, using g_icon_{to,new_for}_string to set a string attribute on the menu item. The attribute is prefixed x-canonical- for now. --- src/indicator-messages.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/indicator-messages.c') diff --git a/src/indicator-messages.c b/src/indicator-messages.c index d898ad6..2824b0c 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -232,21 +232,34 @@ indicator_messages_accessible_desc_updated (IndicatorMessages *self) static void update_root_item (IndicatorMessages * self) { - const gchar *icon_name; + gchar *iconstr; if (g_menu_model_get_n_items (self->menu) == 0) return; - g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, - "&s", &icon_name); + if (g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-icon", "s", &iconstr)) { + GIcon *icon; + GError *error; + + icon = g_icon_new_for_string (iconstr, &error); + if (icon) { + gtk_image_set_from_gicon (GTK_IMAGE (self->image), icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); + } + else { + g_warning ("unable to load icon: %s", error->message); + g_error_free (error); + } + + g_free (iconstr); + } g_free (self->accessible_desc); + self->accessible_desc = NULL; - g_menu_model_get_item_attribute (self->menu, 0, INDICATOR_MENU_ATTRIBUTE_ACCESSIBLE_DESCRIPTION, + g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-accessible-description", "s", &self->accessible_desc); indicator_messages_accessible_desc_updated (self); - - gtk_image_set_from_icon_name (GTK_IMAGE (self->image), icon_name, GTK_ICON_SIZE_MENU); } static void -- cgit v1.2.3