From 4f2dd60a130dcaeb4378219baca1f3d4e9637824 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 31 May 2012 18:55:06 +0200 Subject: Rename AppMenuItem to AppSection --- src/app-section.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 src/app-section.c (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c new file mode 100644 index 0000000..5a5e838 --- /dev/null +++ b/src/app-section.c @@ -0,0 +1,321 @@ +/* +An indicator to show information that is in messaging applications +that the user is using. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "app-section.h" +#include "dbus-data.h" + +typedef struct _AppSectionPrivate AppSectionPrivate; + +struct _AppSectionPrivate +{ + GDesktopAppInfo * appinfo; + guint unreadcount; + + IndicatorDesktopShortcuts * ids; + + GMenu *menu; + GSimpleActionGroup *static_shortcuts; +}; + +#define APP_SECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_SECTION_TYPE, AppSectionPrivate)) + +enum { + PROP_0, + PROP_APPINFO, + NUM_PROPERTIES +}; + +static GParamSpec *properties[NUM_PROPERTIES]; + +/* Prototypes */ +static void app_section_class_init (AppSectionClass *klass); +static void app_section_init (AppSection *self); +static void app_section_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void app_section_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void app_section_dispose (GObject *object); +static void activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata); +static void app_section_set_app_info (AppSection *self, + GDesktopAppInfo *appinfo); + +/* GObject Boilerplate */ +G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); + +static void +app_section_class_init (AppSectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (AppSectionPrivate)); + + object_class->get_property = app_section_get_property; + object_class->set_property = app_section_set_property; + object_class->dispose = app_section_dispose; + + properties[PROP_APPINFO] = g_param_spec_object ("app-info", + "AppInfo", + "The GAppInfo for the app that this menu represents", + G_TYPE_APP_INFO, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); +} + +static void +app_section_init (AppSection *self) +{ + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + + priv->appinfo = NULL; + priv->unreadcount = 0; + + priv->menu = g_menu_new (); + priv->static_shortcuts = g_simple_action_group_new (); + + return; +} + +static void +app_section_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + AppSection *self = APP_SECTION (object); + + switch (property_id) + { + case PROP_APPINFO: + g_value_set_object (value, app_section_get_app_info (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +app_section_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + AppSection *self = APP_SECTION (object); + + switch (property_id) + { + case PROP_APPINFO: + app_section_set_app_info (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} +static void +app_section_dispose (GObject *object) +{ + AppSection * self = APP_SECTION(object); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + + g_clear_object (&priv->menu); + g_clear_object (&priv->static_shortcuts); + + if (priv->ids != NULL) { + g_object_unref(priv->ids); + priv->ids = NULL; + } + + if (priv->appinfo != NULL) { + g_object_unref(priv->appinfo); + priv->appinfo = NULL; + } + + G_OBJECT_CLASS (app_section_parent_class)->dispose (object); +} + +/* Respond to one of the shortcuts getting clicked on. */ +static void +nick_activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata) +{ + const gchar * nick = g_action_get_name (G_ACTION (action)); + AppSection * mi = APP_SECTION (userdata); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(mi); + + g_return_if_fail(priv->ids != NULL); + + if (!indicator_desktop_shortcuts_nick_exec(priv->ids, nick)) { + g_warning("Unable to execute nick '%s' for desktop file '%s'", + nick, g_desktop_app_info_get_filename (priv->appinfo)); + } +} + +static void +app_section_set_app_info (AppSection *self, + GDesktopAppInfo *appinfo) +{ + AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + GSimpleAction *launch; + GMenuItem *menuitem; + GIcon *icon; + gchar *iconstr = NULL; + gchar *label; + + g_return_if_fail (priv->appinfo == NULL); + + if (appinfo == NULL) { + g_warning ("appinfo must not be NULL"); + return; + } + + priv->appinfo = g_object_ref (appinfo); + + icon = g_app_info_get_icon (G_APP_INFO(priv->appinfo)); + iconstr = g_icon_to_string (icon); + + launch = g_simple_action_new ("launch", NULL); + g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); + g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); + + if (priv->unreadcount > 0) + label = g_strdup_printf("%s (%d)", app_section_get_name (self), priv->unreadcount); + else + label = g_strdup(app_section_get_name (self)); + + menuitem = g_menu_item_new (label, "launch"); + g_menu_item_set_attribute (menuitem, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); + g_menu_append_item (priv->menu, menuitem); + + /* Start to build static shortcuts */ + priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); + const gchar ** nicks = indicator_desktop_shortcuts_get_nicks(priv->ids); + gint i; + for (i = 0; nicks[i] != NULL; i++) { + gchar *name; + GSimpleAction *action; + GMenuItem *item; + + name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); + + action = g_simple_action_new (name, NULL); + g_signal_connect(action, "activate", G_CALLBACK (nick_activate_cb), self); + g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); + + item = g_menu_item_new (name, name); + g_menu_append_item (priv->menu, item); + + g_object_unref (item); + g_free(name); + } + + g_free(label); + g_free(iconstr); + g_object_unref (launch); + g_object_unref (menuitem); +} + +AppSection * +app_section_new (GDesktopAppInfo *appinfo) +{ + return g_object_new (APP_SECTION_TYPE, + "app-info", appinfo, + NULL); +} + +static void +activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata) +{ + AppSection * mi = APP_SECTION (userdata); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(mi); + GError *error = NULL; + + if (!g_app_info_launch (G_APP_INFO (priv->appinfo), NULL, NULL, &error)) { + g_warning("Unable to execute application for desktop file '%s'", + g_desktop_app_info_get_filename (priv->appinfo)); + } +} + +guint +app_section_get_count (AppSection * self) +{ + g_return_val_if_fail(IS_APP_SECTION(self), 0); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + + return priv->unreadcount; +} + +const gchar * +app_section_get_name (AppSection * self) +{ + g_return_val_if_fail(IS_APP_SECTION(self), NULL); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + + if (priv->appinfo) { + return g_app_info_get_name(G_APP_INFO(priv->appinfo)); + } + return NULL; +} + +const gchar * +app_section_get_desktop (AppSection * self) +{ + g_return_val_if_fail(IS_APP_SECTION(self), NULL); + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + if (priv->appinfo) + return g_desktop_app_info_get_filename (priv->appinfo); + else + return NULL; +} + +GMenuModel * +app_section_get_menu (AppSection *self) +{ + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + return G_MENU_MODEL (priv->menu); +} + +GAppInfo * +app_section_get_app_info (AppSection *self) +{ + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + return G_APP_INFO (priv->appinfo); +} + -- cgit v1.2.3 From eea45a449eb4de159aab08bad864b27f584af519 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 31 May 2012 19:29:27 +0200 Subject: Put the 'launch' action onto app's menu sections This requires clients to make those menu sections clickable. --- src/app-section.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 5a5e838..5cb2c25 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -192,9 +192,6 @@ app_section_set_app_info (AppSection *self, { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); GSimpleAction *launch; - GMenuItem *menuitem; - GIcon *icon; - gchar *iconstr = NULL; gchar *label; g_return_if_fail (priv->appinfo == NULL); @@ -206,9 +203,6 @@ app_section_set_app_info (AppSection *self, priv->appinfo = g_object_ref (appinfo); - icon = g_app_info_get_icon (G_APP_INFO(priv->appinfo)); - iconstr = g_icon_to_string (icon); - launch = g_simple_action_new ("launch", NULL); g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); @@ -218,10 +212,6 @@ app_section_set_app_info (AppSection *self, else label = g_strdup(app_section_get_name (self)); - menuitem = g_menu_item_new (label, "launch"); - g_menu_item_set_attribute (menuitem, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); - g_menu_append_item (priv->menu, menuitem); - /* Start to build static shortcuts */ priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); const gchar ** nicks = indicator_desktop_shortcuts_get_nicks(priv->ids); @@ -245,9 +235,7 @@ app_section_set_app_info (AppSection *self, } g_free(label); - g_free(iconstr); g_object_unref (launch); - g_object_unref (menuitem); } AppSection * @@ -319,3 +307,24 @@ app_section_get_app_info (AppSection *self) return G_APP_INFO (priv->appinfo); } +GMenuItem * +app_section_create_menu_item (AppSection *self) +{ + AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + GMenuItem *item; + const gchar *name; + gchar *iconstr; + + g_return_val_if_fail (priv->appinfo != NULL, NULL); + + name = g_app_info_get_name (G_APP_INFO (priv->appinfo)); + iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); + + item = g_menu_item_new (name, "launch"); + g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); + g_menu_item_set_section (item, G_MENU_MODEL (priv->menu)); + + g_free(iconstr); + return item; +} + -- cgit v1.2.3 From b4062c831c830df78baeecf092e7c5e7198afada Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 31 May 2012 19:34:44 +0200 Subject: app-section: fix indentation --- src/app-section.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 5cb2c25..6990611 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -55,22 +55,22 @@ enum { static GParamSpec *properties[NUM_PROPERTIES]; /* Prototypes */ -static void app_section_class_init (AppSectionClass *klass); -static void app_section_init (AppSection *self); -static void app_section_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void app_section_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void app_section_dispose (GObject *object); -static void activate_cb (GSimpleAction *action, - GVariant *param, - gpointer userdata); -static void app_section_set_app_info (AppSection *self, - GDesktopAppInfo *appinfo); +static void app_section_class_init (AppSectionClass *klass); +static void app_section_init (AppSection *self); +static void app_section_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void app_section_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void app_section_dispose (GObject *object); +static void activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata); +static void app_section_set_app_info (AppSection *self, + GDesktopAppInfo *appinfo); /* GObject Boilerplate */ G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); @@ -111,9 +111,9 @@ app_section_init (AppSection *self) static void app_section_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) + guint property_id, + GValue *value, + GParamSpec *pspec) { AppSection *self = APP_SECTION (object); @@ -130,9 +130,9 @@ app_section_get_property (GObject *object, static void app_section_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { AppSection *self = APP_SECTION (object); @@ -188,7 +188,7 @@ nick_activate_cb (GSimpleAction *action, static void app_section_set_app_info (AppSection *self, - GDesktopAppInfo *appinfo) + GDesktopAppInfo *appinfo) { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); GSimpleAction *launch; -- cgit v1.2.3 From 21f3cac4cb191430abf89b7cebd0093952c827b0 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 2 Jun 2012 16:44:47 +0200 Subject: Listen to actions exported by applications --- src/app-section.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 6990611..6d00cf1 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -42,6 +42,9 @@ struct _AppSectionPrivate GMenu *menu; GSimpleActionGroup *static_shortcuts; + GActionGroup *actions; + + guint name_watch_id; }; #define APP_SECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_SECTION_TYPE, AppSectionPrivate)) @@ -155,6 +158,12 @@ app_section_dispose (GObject *object) g_clear_object (&priv->menu); g_clear_object (&priv->static_shortcuts); + if (priv->actions) { + g_clear_object (&priv->actions); + g_bus_unwatch_name (priv->name_watch_id); + priv->name_watch_id = 0; + } + if (priv->ids != NULL) { g_object_unref(priv->ids); priv->ids = NULL; @@ -328,3 +337,62 @@ app_section_create_menu_item (AppSection *self) return item; } +static void +application_vanished (GDBusConnection *bus, + const gchar *name, + gpointer user_data) +{ + AppSection *self = user_data; + + app_section_unset_object_path (self); +} + +/* + * app_section_set_object_path: + * @self: an #AppSection + * @bus: a #GDBusConnection + * @bus_name: the bus name of the application + * @object_path: the object path on which the app exports its actions and menus + * + * Sets the D-Bus object path exported by an instance of the application + * associated with @self. Actions and menus exported on that path will be + * shown in the section. + */ +void +app_section_set_object_path (AppSection *self, + GDBusConnection *bus, + const gchar *bus_name, + const gchar *object_path) +{ + AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + + if (priv->actions) { + g_clear_object (&priv->actions); + g_bus_unwatch_name (priv->name_watch_id); + } + + priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, + NULL, application_vanished, + self, NULL); +} + +/* + * app_section_unset_object_path: + * @self: an #AppSection + * + * Unsets the object path set with app_section_set_object_path(). The section + * will return to only showing application name and static shortcuts in the + * menu. + */ +void +app_section_unset_object_path (AppSection *self) +{ + AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + + if (priv->actions) { + g_clear_object (&priv->actions); + g_bus_unwatch_name (priv->name_watch_id); + } +} + -- cgit v1.2.3 From 7989e5c7bb1e012d3703716bfd54e20586bd412c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 2 Jun 2012 16:50:37 +0200 Subject: Listen to menus exported by applications --- src/app-section.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 6d00cf1..9a905bc 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -42,6 +42,8 @@ struct _AppSectionPrivate GMenu *menu; GSimpleActionGroup *static_shortcuts; + + GMenuModel *remote_menu; GActionGroup *actions; guint name_watch_id; @@ -158,12 +160,14 @@ app_section_dispose (GObject *object) g_clear_object (&priv->menu); g_clear_object (&priv->static_shortcuts); - if (priv->actions) { - g_clear_object (&priv->actions); + if (priv->name_watch_id) { g_bus_unwatch_name (priv->name_watch_id); priv->name_watch_id = 0; } + g_clear_object (&priv->actions); + g_clear_object (&priv->remote_menu); + if (priv->ids != NULL) { g_object_unref(priv->ids); priv->ids = NULL; @@ -366,12 +370,14 @@ app_section_set_object_path (AppSection *self, { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); - if (priv->actions) { - g_clear_object (&priv->actions); + if (priv->remote_menu) g_bus_unwatch_name (priv->name_watch_id); - } + g_clear_object (&priv->actions); + g_clear_object (&priv->remote_menu); priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); + priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, NULL, application_vanished, self, NULL); @@ -390,9 +396,9 @@ app_section_unset_object_path (AppSection *self) { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); - if (priv->actions) { - g_clear_object (&priv->actions); + if (priv->remote_menu) g_bus_unwatch_name (priv->name_watch_id); - } + g_clear_object (&priv->actions); + g_clear_object (&priv->remote_menu); } -- cgit v1.2.3 From a6d889c175d136cfb1d63a9c04bb2156f210a09e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 2 Jun 2012 16:57:35 +0200 Subject: app-section: only call g_bus_unwatch_name if we're watching a name --- src/app-section.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 9a905bc..6218f37 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -370,7 +370,7 @@ app_section_set_object_path (AppSection *self, { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); - if (priv->remote_menu) + if (priv->name_watch_id) g_bus_unwatch_name (priv->name_watch_id); g_clear_object (&priv->actions); g_clear_object (&priv->remote_menu); @@ -396,8 +396,10 @@ app_section_unset_object_path (AppSection *self) { AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); - if (priv->remote_menu) + if (priv->name_watch_id) { g_bus_unwatch_name (priv->name_watch_id); + priv->name_watch_id = 0; + } g_clear_object (&priv->actions); g_clear_object (&priv->remote_menu); } -- cgit v1.2.3 From 98538a540ba7a741a68b4cff6d3e192a43d61077 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sun, 3 Jun 2012 12:59:43 +0200 Subject: Reexport application actions --- src/app-section.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 6218f37..f23f412 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -54,6 +54,7 @@ struct _AppSectionPrivate enum { PROP_0, PROP_APPINFO, + PROP_ACTIONS, NUM_PROPERTIES }; @@ -97,6 +98,12 @@ app_section_class_init (AppSectionClass *klass) G_TYPE_APP_INFO, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + properties[PROP_ACTIONS] = g_param_spec_object ("actions", + "Actions", + "The actions exported by this application", + G_TYPE_ACTION_GROUP, + G_PARAM_READABLE); + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } @@ -247,6 +254,9 @@ app_section_set_app_info (AppSection *self, g_free(name); } + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_free(label); g_object_unref (launch); } @@ -306,6 +316,13 @@ app_section_get_desktop (AppSection * self) return NULL; } +GActionGroup * +app_section_get_actions (AppSection *self) +{ + AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + return priv->actions ? priv->actions : G_ACTION_GROUP (priv->static_shortcuts); +} + GMenuModel * app_section_get_menu (AppSection *self) { @@ -381,6 +398,8 @@ app_section_set_object_path (AppSection *self, priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, NULL, application_vanished, self, NULL); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); } /* @@ -402,5 +421,7 @@ app_section_unset_object_path (AppSection *self) } g_clear_object (&priv->actions); g_clear_object (&priv->remote_menu); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); } -- cgit v1.2.3 From 806686a1635bcd72c6e509a85ce8af9246ea551c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sun, 3 Jun 2012 13:07:09 +0200 Subject: Name actions after the shortcut nick instead of its label --- src/app-section.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index f23f412..340bbd7 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -243,11 +243,11 @@ app_section_set_app_info (AppSection *self, name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); - action = g_simple_action_new (name, NULL); + action = g_simple_action_new (nicks[i], NULL); g_signal_connect(action, "activate", G_CALLBACK (nick_activate_cb), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); - item = g_menu_item_new (name, name); + item = g_menu_item_new (name, nicks[i]); g_menu_append_item (priv->menu, item); g_object_unref (item); -- cgit v1.2.3 From 7eae3f378e7d1b3bf4cc291649dfb35b8e2b93eb Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 4 Jun 2012 11:06:31 +0200 Subject: app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member --- src/app-section.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 340bbd7..61d4db3 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -31,8 +31,6 @@ with this program. If not, see . #include "app-section.h" #include "dbus-data.h" -typedef struct _AppSectionPrivate AppSectionPrivate; - struct _AppSectionPrivate { GDesktopAppInfo * appinfo; @@ -49,8 +47,6 @@ struct _AppSectionPrivate guint name_watch_id; }; -#define APP_SECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_SECTION_TYPE, AppSectionPrivate)) - enum { PROP_0, PROP_APPINFO, @@ -110,7 +106,12 @@ app_section_class_init (AppSectionClass *klass) static void app_section_init (AppSection *self) { - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate *priv; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + APP_SECTION_TYPE, + AppSectionPrivate); + priv = self->priv; priv->appinfo = NULL; priv->unreadcount = 0; @@ -162,7 +163,7 @@ static void app_section_dispose (GObject *object) { AppSection * self = APP_SECTION(object); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; g_clear_object (&priv->menu); g_clear_object (&priv->static_shortcuts); @@ -196,7 +197,7 @@ nick_activate_cb (GSimpleAction *action, { const gchar * nick = g_action_get_name (G_ACTION (action)); AppSection * mi = APP_SECTION (userdata); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(mi); + AppSectionPrivate * priv = mi->priv; g_return_if_fail(priv->ids != NULL); @@ -210,7 +211,7 @@ static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo) { - AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + AppSectionPrivate *priv = self->priv; GSimpleAction *launch; gchar *label; @@ -275,7 +276,7 @@ activate_cb (GSimpleAction *action, gpointer userdata) { AppSection * mi = APP_SECTION (userdata); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(mi); + AppSectionPrivate * priv = mi->priv; GError *error = NULL; if (!g_app_info_launch (G_APP_INFO (priv->appinfo), NULL, NULL, &error)) { @@ -288,7 +289,7 @@ guint app_section_get_count (AppSection * self) { g_return_val_if_fail(IS_APP_SECTION(self), 0); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; return priv->unreadcount; } @@ -297,7 +298,7 @@ const gchar * app_section_get_name (AppSection * self) { g_return_val_if_fail(IS_APP_SECTION(self), NULL); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; if (priv->appinfo) { return g_app_info_get_name(G_APP_INFO(priv->appinfo)); @@ -309,7 +310,7 @@ const gchar * app_section_get_desktop (AppSection * self) { g_return_val_if_fail(IS_APP_SECTION(self), NULL); - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; if (priv->appinfo) return g_desktop_app_info_get_filename (priv->appinfo); else @@ -319,28 +320,28 @@ app_section_get_desktop (AppSection * self) GActionGroup * app_section_get_actions (AppSection *self) { - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; return priv->actions ? priv->actions : G_ACTION_GROUP (priv->static_shortcuts); } GMenuModel * app_section_get_menu (AppSection *self) { - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; return G_MENU_MODEL (priv->menu); } GAppInfo * app_section_get_app_info (AppSection *self) { - AppSectionPrivate * priv = APP_SECTION_GET_PRIVATE(self); + AppSectionPrivate * priv = self->priv; return G_APP_INFO (priv->appinfo); } GMenuItem * app_section_create_menu_item (AppSection *self) { - AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + AppSectionPrivate *priv = self->priv; GMenuItem *item; const gchar *name; gchar *iconstr; @@ -385,7 +386,7 @@ app_section_set_object_path (AppSection *self, const gchar *bus_name, const gchar *object_path) { - AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + AppSectionPrivate *priv = self->priv; if (priv->name_watch_id) g_bus_unwatch_name (priv->name_watch_id); @@ -413,7 +414,7 @@ app_section_set_object_path (AppSection *self, void app_section_unset_object_path (AppSection *self) { - AppSectionPrivate *priv = APP_SECTION_GET_PRIVATE (self); + AppSectionPrivate *priv = self->priv; if (priv->name_watch_id) { g_bus_unwatch_name (priv->name_watch_id); -- cgit v1.2.3 From cd8e4e8d16d67c6601a0536fc2554bc45c10728e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 4 Jun 2012 11:56:15 +0200 Subject: Reexport application menu as a separate section below the shortcuts --- src/app-section.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 61d4db3..b59bfc1 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -391,11 +391,17 @@ app_section_set_object_path (AppSection *self, if (priv->name_watch_id) g_bus_unwatch_name (priv->name_watch_id); g_clear_object (&priv->actions); - g_clear_object (&priv->remote_menu); + + if (priv->remote_menu) { + g_menu_remove (priv->menu, 0); + g_clear_object (&priv->remote_menu); + } priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); + g_menu_append_section (priv->menu, NULL, priv->remote_menu); + priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, NULL, application_vanished, self, NULL); @@ -421,7 +427,11 @@ app_section_unset_object_path (AppSection *self) priv->name_watch_id = 0; } g_clear_object (&priv->actions); - g_clear_object (&priv->remote_menu); + + if (priv->remote_menu) { + g_menu_remove (priv->menu, 0); + g_clear_object (&priv->remote_menu); + } g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); } -- cgit v1.2.3 From 787dff35a9a9e0c491e960754b8bbdeb46ae800c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 25 Jun 2012 16:40:26 +0200 Subject: Put launcher and shortcut menu items into the same gmenu section --- src/app-section.c | 58 +++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index b59bfc1..7bbbbbb 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -207,13 +207,25 @@ nick_activate_cb (GSimpleAction *action, } } +static void +g_menu_item_set_icon (GMenuItem *item, + GIcon *icon) +{ + gchar *iconstr; + + iconstr = g_icon_to_string (icon); + g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); + + g_free (iconstr); +} + static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo) { AppSectionPrivate *priv = self->priv; GSimpleAction *launch; - gchar *label; + GMenuItem *item; g_return_if_fail (priv->appinfo == NULL); @@ -228,10 +240,9 @@ app_section_set_app_info (AppSection *self, g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); - if (priv->unreadcount > 0) - label = g_strdup_printf("%s (%d)", app_section_get_name (self), priv->unreadcount); - else - label = g_strdup(app_section_get_name (self)); + item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); + g_menu_item_set_icon (item, g_app_info_get_icon (G_APP_INFO (priv->appinfo))); + g_menu_append_item (priv->menu, item); /* Start to build static shortcuts */ priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); @@ -258,7 +269,6 @@ app_section_set_app_info (AppSection *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); - g_free(label); g_object_unref (launch); } @@ -338,27 +348,6 @@ app_section_get_app_info (AppSection *self) return G_APP_INFO (priv->appinfo); } -GMenuItem * -app_section_create_menu_item (AppSection *self) -{ - AppSectionPrivate *priv = self->priv; - GMenuItem *item; - const gchar *name; - gchar *iconstr; - - g_return_val_if_fail (priv->appinfo != NULL, NULL); - - name = g_app_info_get_name (G_APP_INFO (priv->appinfo)); - iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); - - item = g_menu_item_new (name, "launch"); - g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); - g_menu_item_set_section (item, G_MENU_MODEL (priv->menu)); - - g_free(iconstr); - return item; -} - static void application_vanished (GDBusConnection *bus, const gchar *name, @@ -388,14 +377,8 @@ app_section_set_object_path (AppSection *self, { AppSectionPrivate *priv = self->priv; - if (priv->name_watch_id) - g_bus_unwatch_name (priv->name_watch_id); - g_clear_object (&priv->actions); - - if (priv->remote_menu) { - g_menu_remove (priv->menu, 0); - g_clear_object (&priv->remote_menu); - } + g_object_freeze_notify (G_OBJECT (self)); + app_section_unset_object_path (self); priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); @@ -407,6 +390,7 @@ app_section_set_object_path (AppSection *self, self, NULL); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_object_thaw_notify (G_OBJECT (self)); } /* @@ -429,7 +413,9 @@ app_section_unset_object_path (AppSection *self) g_clear_object (&priv->actions); if (priv->remote_menu) { - g_menu_remove (priv->menu, 0); + /* the last menu item points is linked to the app's menumodel */ + gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->menu)); + g_menu_remove (priv->menu, n_items -1); g_clear_object (&priv->remote_menu); } -- cgit v1.2.3 From be44bb8644730b598fdc1990ab81c1f067dc2353 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 26 Jun 2012 00:46:00 +0200 Subject: messages-service: move gmenu utility functions into gmenuutils.[ch] As a neat side-effect, this fixes a memory leak in app-section.c. --- src/app-section.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 7bbbbbb..1662a9f 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -30,6 +30,7 @@ with this program. If not, see . #include #include "app-section.h" #include "dbus-data.h" +#include "gmenuutils.h" struct _AppSectionPrivate { @@ -207,25 +208,12 @@ nick_activate_cb (GSimpleAction *action, } } -static void -g_menu_item_set_icon (GMenuItem *item, - GIcon *icon) -{ - gchar *iconstr; - - iconstr = g_icon_to_string (icon); - g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconstr); - - g_free (iconstr); -} - static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo) { AppSectionPrivate *priv = self->priv; GSimpleAction *launch; - GMenuItem *item; g_return_if_fail (priv->appinfo == NULL); @@ -240,9 +228,10 @@ app_section_set_app_info (AppSection *self, g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); - item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); - g_menu_item_set_icon (item, g_app_info_get_icon (G_APP_INFO (priv->appinfo))); - g_menu_append_item (priv->menu, item); + g_menu_append_with_icon (priv->menu, + g_app_info_get_name (G_APP_INFO (priv->appinfo)), + g_app_info_get_icon (G_APP_INFO (priv->appinfo)), + "launch"); /* Start to build static shortcuts */ priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); -- cgit v1.2.3 From 4dc6e54dd0a5ebba4eb4e26d09ecfde8c9a9580b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 26 Jun 2012 00:49:14 +0200 Subject: app-section.c: get rid of unnecessary local item --- src/app-section.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 1662a9f..472fb6c 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -240,7 +240,6 @@ app_section_set_app_info (AppSection *self, for (i = 0; nicks[i] != NULL; i++) { gchar *name; GSimpleAction *action; - GMenuItem *item; name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); @@ -248,10 +247,8 @@ app_section_set_app_info (AppSection *self, g_signal_connect(action, "activate", G_CALLBACK (nick_activate_cb), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); - item = g_menu_item_new (name, nicks[i]); - g_menu_append_item (priv->menu, item); + g_menu_append (priv->menu, name, nicks[i]); - g_object_unref (item); g_free(name); } -- cgit v1.2.3 From 93db8c38f2252cb4d506d90721446c0ad524ca3b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 17:25:34 +0200 Subject: Add draws-attention flag to source actions AppSections watch those flags for associated sources and mux them into a draws-attention property for the whole section. --- src/app-section.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 472fb6c..35a842f 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -45,6 +45,8 @@ struct _AppSectionPrivate GMenuModel *remote_menu; GActionGroup *actions; + gboolean draws_attention; + guint name_watch_id; }; @@ -52,6 +54,7 @@ enum { PROP_0, PROP_APPINFO, PROP_ACTIONS, + PROP_DRAWS_ATTENTION, NUM_PROPERTIES }; @@ -74,6 +77,18 @@ static void activate_cb (GSimpleAction *action, gpointer userdata); static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo); +static gboolean any_action_draws_attention (GActionGroup *group, + const gchar *ignored_action); +static void action_added (GActionGroup *group, + const gchar *action_name, + gpointer user_data); +static void action_state_changed (GActionGroup *group, + const gchar *action_name, + GVariant *value, + gpointer user_data); +static void action_removed (GActionGroup *group, + const gchar *action_name, + gpointer user_data); /* GObject Boilerplate */ G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); @@ -101,6 +116,12 @@ app_section_class_init (AppSectionClass *klass) G_TYPE_ACTION_GROUP, G_PARAM_READABLE); + properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", + "Draws attention", + "Whether the section currently draws attention", + FALSE, + G_PARAM_READABLE); + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } @@ -120,6 +141,8 @@ app_section_init (AppSection *self) priv->menu = g_menu_new (); priv->static_shortcuts = g_simple_action_group_new (); + priv->draws_attention = FALSE; + return; } @@ -137,6 +160,10 @@ app_section_get_property (GObject *object, g_value_set_object (value, app_section_get_app_info (self)); break; + case PROP_DRAWS_ATTENTION: + g_value_set_boolean (value, app_section_get_draws_attention (self)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -174,7 +201,15 @@ app_section_dispose (GObject *object) priv->name_watch_id = 0; } - g_clear_object (&priv->actions); + if (priv->actions) { + g_object_disconnect (priv->actions, + "any_signal::action-added", action_added, self, + "any_signal::action-state-changed", action_state_changed, self, + "any_signal::action-removed", action_removed, self, + NULL); + g_clear_object (&priv->actions); + } + g_clear_object (&priv->remote_menu); if (priv->ids != NULL) { @@ -334,6 +369,13 @@ app_section_get_app_info (AppSection *self) return G_APP_INFO (priv->appinfo); } +gboolean +app_section_get_draws_attention (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + return priv->draws_attention; +} + static void application_vanished (GDBusConnection *bus, const gchar *name, @@ -367,6 +409,14 @@ app_section_set_object_path (AppSection *self, app_section_unset_object_path (self); priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + + priv->draws_attention = any_action_draws_attention (priv->actions, NULL); + g_object_connect (priv->actions, + "signal::action-added", action_added, self, + "signal::action-state-changed", action_state_changed, self, + "signal::action-removed", action_removed, self, + NULL); + priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); g_menu_append_section (priv->menu, NULL, priv->remote_menu); @@ -376,6 +426,7 @@ app_section_set_object_path (AppSection *self, self, NULL); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); g_object_thaw_notify (G_OBJECT (self)); } @@ -396,7 +447,15 @@ app_section_unset_object_path (AppSection *self) g_bus_unwatch_name (priv->name_watch_id); priv->name_watch_id = 0; } - g_clear_object (&priv->actions); + + if (priv->actions) { + g_object_disconnect (priv->actions, + "any_signal::action-added", action_added, self, + "any_signal::action-state-changed", action_state_changed, self, + "any_signal::action-removed", action_removed, self, + NULL); + g_clear_object (&priv->actions); + } if (priv->remote_menu) { /* the last menu item points is linked to the app's menumodel */ @@ -405,6 +464,94 @@ app_section_unset_object_path (AppSection *self) g_clear_object (&priv->remote_menu); } + priv->draws_attention = FALSE; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); } +static gboolean +action_draws_attention (GVariant *state) +{ + gboolean attention; + + if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)"))) + g_variant_get_child (state, 3, "b", &attention); + else + attention = FALSE; + + return attention; +} + +static gboolean +any_action_draws_attention (GActionGroup *group, + const gchar *ignored_action) +{ + gchar **actions; + gchar **it; + gboolean attention = FALSE; + + actions = g_action_group_list_actions (group); + + for (it = actions; *it && !attention; it++) { + GVariant *state; + + if (ignored_action && g_str_equal (ignored_action, *it)) + continue; + + state = g_action_group_get_action_state (group, *it); + if (state) { + attention = action_draws_attention (state); + g_variant_unref (state); + } + } + + g_strfreev (actions); + return attention; +} + +static void +action_added (GActionGroup *group, + const gchar *action_name, + gpointer user_data) +{ + AppSection *self = user_data; + GVariant *state; + + state = g_action_group_get_action_state (group, action_name); + if (state) { + self->priv->draws_attention |= action_draws_attention (state); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_variant_unref (state); + } +} + +static void +action_state_changed (GActionGroup *group, + const gchar *action_name, + GVariant *value, + gpointer user_data) +{ + AppSection *self = user_data; + + self->priv->draws_attention = any_action_draws_attention (group, NULL); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); +} + +static void +action_removed (GActionGroup *group, + const gchar *action_name, + gpointer user_data) +{ + AppSection *self = user_data; + GVariant *state; + + state = g_action_group_get_action_state (group, action_name); + if (!state) + return; + + self->priv->draws_attention = any_action_draws_attention (group, action_name); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + + g_variant_unref (state); +} -- cgit v1.2.3 From 58bb62e4b6f88e2f6688afe2e94ac0d954eacadf Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 17:56:32 +0200 Subject: Make "Clear" work again --- src/app-section.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 35a842f..e7a2e1d 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -89,6 +89,7 @@ static void action_state_changed (GActionGroup *group, static void action_removed (GActionGroup *group, const gchar *action_name, gpointer user_data); +static gboolean action_draws_attention (GVariant *state); /* GObject Boilerplate */ G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); @@ -376,6 +377,44 @@ app_section_get_draws_attention (AppSection *self) return priv->draws_attention; } +void +app_section_clear_draws_attention (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + gchar **action_names; + gchar **it; + + if (priv->actions == NULL) + return; + + action_names = g_action_group_list_actions (priv->actions); + + for (it = action_names; *it; it++) { + GVariant *state; + + state = g_action_group_get_action_state (priv->actions, *it); + if (!state) + continue; + + /* clear draws-attention while preserving other state */ + if (action_draws_attention (state)) { + guint32 count; + gint64 time; + const gchar *str; + GVariant *new_state; + + g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); + + new_state = g_variant_new ("(uxsb)", count, time, str, FALSE); + g_action_group_change_action_state (priv->actions, *it, new_state); + } + + g_variant_unref (state); + } + + g_strfreev (action_names); +} + static void application_vanished (GDBusConnection *bus, const gchar *name, -- cgit v1.2.3 From 37acacae18286dbfeceacc74db8e5ff02ae8f8b2 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Jun 2012 23:55:52 +0200 Subject: Only show chat section when necessary The chat section is only shown when an application that is registered to use it is running. Applications are registered if their desktop file contains: X-MessagingMenu-UsesChatStatus: true --- src/app-section.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index e7a2e1d..fb3d8f9 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -46,6 +46,7 @@ struct _AppSectionPrivate GActionGroup *actions; gboolean draws_attention; + gboolean uses_chat_status; guint name_watch_id; }; @@ -55,6 +56,7 @@ enum { PROP_APPINFO, PROP_ACTIONS, PROP_DRAWS_ATTENTION, + PROP_USES_CHAT_STATUS, NUM_PROPERTIES }; @@ -123,6 +125,12 @@ app_section_class_init (AppSectionClass *klass) FALSE, G_PARAM_READABLE); + properties[PROP_USES_CHAT_STATUS] = g_param_spec_boolean ("uses-chat-status", + "Uses chat status", + "Whether the section uses the global chat status", + FALSE, + G_PARAM_READABLE); + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); } @@ -165,6 +173,10 @@ app_section_get_property (GObject *object, g_value_set_boolean (value, app_section_get_draws_attention (self)); break; + case PROP_USES_CHAT_STATUS: + g_value_set_boolean (value, app_section_get_uses_chat_status (self)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -244,12 +256,59 @@ nick_activate_cb (GSimpleAction *action, } } +static void +keyfile_loaded (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + AppSection *self = user_data; + gchar *contents; + gsize length; + GKeyFile *keyfile; + GError *error = NULL; + + if (!g_file_load_contents_finish (G_FILE (source_object), result, + &contents, &length, NULL, &error)) { + g_warning ("could not read key file: %s", error->message); + g_error_free (error); + return; + } + + keyfile = g_key_file_new (); + if (!g_key_file_load_from_data (keyfile, contents, length, 0, &error)) { + g_warning ("could not read key file: %s", error->message); + g_error_free (error); + goto out; + } + + self->priv->uses_chat_status = g_key_file_get_boolean (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + "X-MessagingMenu-UsesChatStatus", + &error); + if (error) { + if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { + g_warning ("could not read X-MessagingMenu-UsesChatSection: %s", + error->message); + } + g_error_free (error); + goto out; + } + + if (self->priv->uses_chat_status) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); + +out: + g_key_file_free (keyfile); + g_free (contents); +} + static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo) { AppSectionPrivate *priv = self->priv; GSimpleAction *launch; + GFile *keyfile; g_return_if_fail (priv->appinfo == NULL); @@ -288,6 +347,10 @@ app_section_set_app_info (AppSection *self, g_free(name); } + keyfile = g_file_new_for_path (g_desktop_app_info_get_filename (priv->appinfo)); + g_file_load_contents_async (keyfile, NULL, keyfile_loaded, self); + g_object_unref (keyfile); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); @@ -466,6 +529,7 @@ app_section_set_object_path (AppSection *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); g_object_thaw_notify (G_OBJECT (self)); } @@ -507,6 +571,7 @@ app_section_unset_object_path (AppSection *self) g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); } static gboolean @@ -594,3 +659,12 @@ action_removed (GActionGroup *group, g_variant_unref (state); } + +gboolean +app_section_get_uses_chat_status (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + + /* chat status is only useful when the app is running */ + return priv->uses_chat_status && priv->actions; +} -- cgit v1.2.3 From 4c1f8ad57ce2f1865359d343c04dcfb1bedf2109 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 29 Jun 2012 19:56:56 +0200 Subject: X-MessagingMenu-UsesChatStatus --> X-MessagingMenu-UsesChatSection --- src/app-section.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index fb3d8f9..c5b0731 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -283,7 +283,7 @@ keyfile_loaded (GObject *source_object, self->priv->uses_chat_status = g_key_file_get_boolean (keyfile, G_KEY_FILE_DESKTOP_GROUP, - "X-MessagingMenu-UsesChatStatus", + "X-MessagingMenu-UsesChatSection", &error); if (error) { if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { -- cgit v1.2.3 From 75ae6cbac0dc1d2c423d27a4d9f460a87139f0fe Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 19 Aug 2012 15:41:23 -0500 Subject: add lars as co-author of app-section --- src/app-section.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index c5b0731..f6cf15f 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -2,9 +2,10 @@ An indicator to show information that is in messaging applications that the user is using. -Copyright 2009 Canonical Ltd. +Copyright 2012 Canonical Ltd. Authors: + Lars Uebernickel Ted Gould This program is free software: you can redistribute it and/or modify it -- cgit v1.2.3 From 302ec8cd11ba3ec3a2d23d78bdd41974e92f63f6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 19 Aug 2012 15:42:48 -0500 Subject: in app-section.c's dispose(), use g_clear_object() for priv.ids and priv.keyfile --- src/app-section.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index f6cf15f..179be59 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -225,16 +225,8 @@ app_section_dispose (GObject *object) } g_clear_object (&priv->remote_menu); - - if (priv->ids != NULL) { - g_object_unref(priv->ids); - priv->ids = NULL; - } - - if (priv->appinfo != NULL) { - g_object_unref(priv->appinfo); - priv->appinfo = NULL; - } + g_clear_object (&priv->ids); + g_clear_object (&priv->appinfo); G_OBJECT_CLASS (app_section_parent_class)->dispose (object); } -- cgit v1.2.3 From ade3b76a6d41bf95b82e6c19b09c7142c79bf31e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 19 Aug 2012 15:49:24 -0500 Subject: add sanity checks to args passed in the public API --- src/app-section.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 179be59..0b6a4b1 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -252,7 +252,7 @@ nick_activate_cb (GSimpleAction *action, static void keyfile_loaded (GObject *source_object, GAsyncResult *result, - gpointer user_data) + gpointer user_data) { AppSection *self = user_data; gchar *contents; @@ -408,6 +408,7 @@ app_section_get_desktop (AppSection * self) GActionGroup * app_section_get_actions (AppSection *self) { + g_return_val_if_fail(IS_APP_SECTION(self), NULL); AppSectionPrivate * priv = self->priv; return priv->actions ? priv->actions : G_ACTION_GROUP (priv->static_shortcuts); } @@ -415,6 +416,7 @@ app_section_get_actions (AppSection *self) GMenuModel * app_section_get_menu (AppSection *self) { + g_return_val_if_fail(IS_APP_SECTION(self), NULL); AppSectionPrivate * priv = self->priv; return G_MENU_MODEL (priv->menu); } @@ -422,6 +424,7 @@ app_section_get_menu (AppSection *self) GAppInfo * app_section_get_app_info (AppSection *self) { + g_return_val_if_fail(IS_APP_SECTION(self), NULL); AppSectionPrivate * priv = self->priv; return G_APP_INFO (priv->appinfo); } @@ -429,6 +432,7 @@ app_section_get_app_info (AppSection *self) gboolean app_section_get_draws_attention (AppSection *self) { + g_return_val_if_fail(IS_APP_SECTION(self), FALSE); AppSectionPrivate * priv = self->priv; return priv->draws_attention; } @@ -436,6 +440,7 @@ app_section_get_draws_attention (AppSection *self) void app_section_clear_draws_attention (AppSection *self) { + g_return_if_fail (IS_APP_SECTION(self)); AppSectionPrivate * priv = self->priv; gchar **action_names; gchar **it; @@ -498,6 +503,7 @@ app_section_set_object_path (AppSection *self, const gchar *bus_name, const gchar *object_path) { + g_return_if_fail (IS_APP_SECTION(self)); AppSectionPrivate *priv = self->priv; g_object_freeze_notify (G_OBJECT (self)); @@ -537,6 +543,7 @@ app_section_set_object_path (AppSection *self, void app_section_unset_object_path (AppSection *self) { + g_return_if_fail (IS_APP_SECTION(self)); AppSectionPrivate *priv = self->priv; if (priv->name_watch_id) { @@ -656,6 +663,7 @@ action_removed (GActionGroup *group, gboolean app_section_get_uses_chat_status (AppSection *self) { + g_return_val_if_fail (IS_APP_SECTION(self), FALSE); AppSectionPrivate * priv = self->priv; /* chat status is only useful when the app is running */ -- 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/app-section.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index c5b0731..1627d40 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -77,6 +77,9 @@ static void app_section_dispose (GObject *object); static void activate_cb (GSimpleAction *action, GVariant *param, gpointer userdata); +static void launch_action_change_state (GSimpleAction *action, + GVariant *value, + gpointer user_data); static void app_section_set_app_info (AppSection *self, GDesktopAppInfo *appinfo); static gboolean any_action_draws_attention (GActionGroup *group, @@ -309,6 +312,8 @@ app_section_set_app_info (AppSection *self, AppSectionPrivate *priv = self->priv; GSimpleAction *launch; GFile *keyfile; + GMenuItem *item; + gchar *iconname; g_return_if_fail (priv->appinfo == NULL); @@ -319,14 +324,19 @@ app_section_set_app_info (AppSection *self, priv->appinfo = g_object_ref (appinfo); - launch = g_simple_action_new ("launch", NULL); + launch = g_simple_action_new_stateful ("launch", NULL, g_variant_new_boolean (FALSE)); g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); + g_signal_connect (launch, "change-state", G_CALLBACK (launch_action_change_state), self); g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); - g_menu_append_with_icon (priv->menu, - g_app_info_get_name (G_APP_INFO (priv->appinfo)), - g_app_info_get_icon (G_APP_INFO (priv->appinfo)), - "launch"); + item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem"); + iconname = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); + g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconname); + g_free (iconname); + + g_menu_append_item (priv->menu, item); + g_object_unref (item); /* Start to build static shortcuts */ priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); @@ -380,6 +390,14 @@ activate_cb (GSimpleAction *action, } } +static void +launch_action_change_state (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + g_simple_action_set_state (action, value); +} + guint app_section_get_count (AppSection * self) { @@ -531,6 +549,9 @@ app_section_set_object_path (AppSection *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); g_object_thaw_notify (G_OBJECT (self)); + + g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), + "launch", g_variant_new_boolean (TRUE)); } /* @@ -572,6 +593,9 @@ app_section_unset_object_path (AppSection *self) g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); + + g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), + "launch", g_variant_new_boolean (FALSE)); } static gboolean -- cgit v1.2.3 From daec6bad9a1a2c8a994b174e21e46f3865e45208 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 20 Aug 2012 22:08:15 +0200 Subject: Export both static shortcuts also when the app is running --- src/app-section.c | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 1627d40..d80e750 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -31,6 +31,7 @@ with this program. If not, see . #include "app-section.h" #include "dbus-data.h" #include "gmenuutils.h" +#include "gactionmuxer.h" struct _AppSectionPrivate { @@ -40,10 +41,11 @@ struct _AppSectionPrivate IndicatorDesktopShortcuts * ids; GMenu *menu; - GSimpleActionGroup *static_shortcuts; - GMenuModel *remote_menu; - GActionGroup *actions; + + GSimpleActionGroup *static_shortcuts; + GActionGroup *source_actions; + GActionMuxer *muxer; gboolean draws_attention; gboolean uses_chat_status; @@ -153,6 +155,9 @@ app_section_init (AppSection *self) priv->menu = g_menu_new (); priv->static_shortcuts = g_simple_action_group_new (); + priv->muxer = g_action_muxer_new (); + g_action_muxer_insert (priv->muxer, NULL, G_ACTION_GROUP (priv->static_shortcuts)); + priv->draws_attention = FALSE; return; @@ -217,13 +222,14 @@ app_section_dispose (GObject *object) priv->name_watch_id = 0; } - if (priv->actions) { - g_object_disconnect (priv->actions, + if (priv->source_actions) { + g_action_muxer_remove (priv->muxer, "source"); + g_object_disconnect (priv->source_actions, "any_signal::action-added", action_added, self, "any_signal::action-state-changed", action_state_changed, self, "any_signal::action-removed", action_removed, self, NULL); - g_clear_object (&priv->actions); + g_clear_object (&priv->source_actions); } g_clear_object (&priv->remote_menu); @@ -434,7 +440,7 @@ GActionGroup * app_section_get_actions (AppSection *self) { AppSectionPrivate * priv = self->priv; - return priv->actions ? priv->actions : G_ACTION_GROUP (priv->static_shortcuts); + return G_ACTION_GROUP (priv->muxer); } GMenuModel * @@ -465,15 +471,15 @@ app_section_clear_draws_attention (AppSection *self) gchar **action_names; gchar **it; - if (priv->actions == NULL) + if (priv->source_actions == NULL) return; - action_names = g_action_group_list_actions (priv->actions); + action_names = g_action_group_list_actions (priv->source_actions); for (it = action_names; *it; it++) { GVariant *state; - state = g_action_group_get_action_state (priv->actions, *it); + state = g_action_group_get_action_state (priv->source_actions, *it); if (!state) continue; @@ -487,7 +493,7 @@ app_section_clear_draws_attention (AppSection *self) g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); new_state = g_variant_new ("(uxsb)", count, time, str, FALSE); - g_action_group_change_action_state (priv->actions, *it, new_state); + g_action_group_change_action_state (priv->source_actions, *it, new_state); } g_variant_unref (state); @@ -524,14 +530,16 @@ app_section_set_object_path (AppSection *self, const gchar *object_path) { AppSectionPrivate *priv = self->priv; + GMenuItem *item; g_object_freeze_notify (G_OBJECT (self)); app_section_unset_object_path (self); - priv->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + priv->source_actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + g_action_muxer_insert (priv->muxer, "source", priv->source_actions); - priv->draws_attention = any_action_draws_attention (priv->actions, NULL); - g_object_connect (priv->actions, + priv->draws_attention = any_action_draws_attention (priv->source_actions, NULL); + g_object_connect (priv->source_actions, "signal::action-added", action_added, self, "signal::action-state-changed", action_state_changed, self, "signal::action-removed", action_removed, self, @@ -539,7 +547,10 @@ app_section_set_object_path (AppSection *self, priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); - g_menu_append_section (priv->menu, NULL, priv->remote_menu); + item = g_menu_item_new_section (NULL, priv->remote_menu); + g_menu_item_set_attribute (item, "action-namespace", "s", "source"); + g_menu_append_item (priv->menu, item); + g_object_unref (item); priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, NULL, application_vanished, @@ -572,13 +583,13 @@ app_section_unset_object_path (AppSection *self) priv->name_watch_id = 0; } - if (priv->actions) { - g_object_disconnect (priv->actions, + if (priv->source_actions) { + g_object_disconnect (priv->source_actions, "any_signal::action-added", action_added, self, "any_signal::action-state-changed", action_state_changed, self, "any_signal::action-removed", action_removed, self, NULL); - g_clear_object (&priv->actions); + g_clear_object (&priv->source_actions); } if (priv->remote_menu) { @@ -690,5 +701,5 @@ app_section_get_uses_chat_status (AppSection *self) AppSectionPrivate * priv = self->priv; /* chat status is only useful when the app is running */ - return priv->uses_chat_status && priv->actions; + return priv->uses_chat_status && priv->source_actions; } -- cgit v1.2.3 From ce52ecafde8a9fccb22f870d98e396e3df7472cd Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 20 Aug 2012 22:10:17 +0200 Subject: app-section: rename remote_menu to source_menu Because it contains the message sources. --- src/app-section.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index d80e750..9e83f13 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -41,7 +41,7 @@ struct _AppSectionPrivate IndicatorDesktopShortcuts * ids; GMenu *menu; - GMenuModel *remote_menu; + GMenuModel *source_menu; GSimpleActionGroup *static_shortcuts; GActionGroup *source_actions; @@ -232,7 +232,7 @@ app_section_dispose (GObject *object) g_clear_object (&priv->source_actions); } - g_clear_object (&priv->remote_menu); + g_clear_object (&priv->source_menu); if (priv->ids != NULL) { g_object_unref(priv->ids); @@ -545,9 +545,9 @@ app_section_set_object_path (AppSection *self, "signal::action-removed", action_removed, self, NULL); - priv->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); + priv->source_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); - item = g_menu_item_new_section (NULL, priv->remote_menu); + item = g_menu_item_new_section (NULL, priv->source_menu); g_menu_item_set_attribute (item, "action-namespace", "s", "source"); g_menu_append_item (priv->menu, item); g_object_unref (item); @@ -592,11 +592,11 @@ app_section_unset_object_path (AppSection *self) g_clear_object (&priv->source_actions); } - if (priv->remote_menu) { + if (priv->source_menu) { /* the last menu item points is linked to the app's menumodel */ gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->menu)); g_menu_remove (priv->menu, n_items -1); - g_clear_object (&priv->remote_menu); + g_clear_object (&priv->source_menu); } priv->draws_attention = FALSE; -- 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/app-section.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/app-section.c') diff --git a/src/app-section.c b/src/app-section.c index 1602ac6..70bf21e 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -312,7 +312,7 @@ app_section_set_app_info (AppSection *self, GSimpleAction *launch; GFile *keyfile; GMenuItem *item; - gchar *iconname; + gchar *iconstr; g_return_if_fail (priv->appinfo == NULL); @@ -330,9 +330,9 @@ app_section_set_app_info (AppSection *self, item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem"); - iconname = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); - g_menu_item_set_attribute (item, INDICATOR_MENU_ATTRIBUTE_ICON_NAME, "s", iconname); - g_free (iconname); + iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); + g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + g_free (iconstr); g_menu_append_item (priv->menu, item); g_object_unref (item); -- cgit v1.2.3