From 1f621cbbbfe9bc65f4fbce2ff2bb57ef8badad82 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Aug 2012 00:52:58 -0500 Subject: in app-section.c's dispose(), clear the muxer object --- src/app-section.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app-section.c b/src/app-section.c index 1602ac6..4cccb6c 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -233,6 +233,8 @@ app_section_dispose (GObject *object) g_clear_object (&priv->source_actions); } + g_clear_object (&priv->muxer); + g_clear_object (&priv->source_menu); g_clear_object (&priv->ids); g_clear_object (&priv->appinfo); -- cgit v1.2.3 From 19f5fdbb523167af107267c2bb28a810b5a548a2 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Aug 2012 00:54:03 -0500 Subject: in app-section's app_section_set_app_info(), don't leak the nicks' actions --- src/app-section.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app-section.c b/src/app-section.c index 4cccb6c..fcb75d9 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -352,6 +352,7 @@ app_section_set_app_info (AppSection *self, 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)); + g_object_unref (action); g_menu_append (priv->menu, name, nicks[i]); -- cgit v1.2.3 From 2f2630580f5e473f0748fcedd52164c350285a00 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 21 Aug 2012 00:55:26 -0500 Subject: in app-section.c's activate_cb(), don't leak the GError if we can't launch --- src/app-section.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app-section.c b/src/app-section.c index fcb75d9..f922dca 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -387,8 +387,10 @@ activate_cb (GSimpleAction *action, 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)); + g_warning("Unable to execute application for desktop file '%s': %s", + g_desktop_app_info_get_filename (priv->appinfo), + error->message); + g_error_free (error); } } -- cgit v1.2.3 From 17d00fcd9f594ee938595a8c9a337cbd8c98cd27 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 21 Aug 2012 13:26:30 +0200 Subject: Bump glib and gtk dependencies --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f9f00e9..4bf55b0 100644 --- a/configure.ac +++ b/configure.ac @@ -38,11 +38,11 @@ AC_PROG_CXX # Dependencies ########################### -GTK_REQUIRED_VERSION=3.0 -GIO_UNIX_REQUIRED_VERSION=2.18 +GTK_REQUIRED_VERSION=3.5.12 +GIO_UNIX_REQUIRED_VERSION=2.33.10 PANEL_REQUIRED_VERSION=2.0.0 INDICATOR_REQUIRED_VERSION=0.3.19 -GLIB_REQUIRED_VERSION=2.31.20 +GLIB_REQUIRED_VERSION=2.33.10 INTROSPECTION_REQUIRED_VERSION=1.32.0 PKG_CHECK_MODULES(APPLET, gtk+-3.0 >= $GTK_REQUIRED_VERSION -- cgit v1.2.3 From 7272017b49f5ee3aa9033e12271986cd5534f1c1 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 21 Aug 2012 13:27:02 +0200 Subject: configure.ac: remove unused variable --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4bf55b0..d9270dd 100644 --- a/configure.ac +++ b/configure.ac @@ -40,7 +40,6 @@ AC_PROG_CXX GTK_REQUIRED_VERSION=3.5.12 GIO_UNIX_REQUIRED_VERSION=2.33.10 -PANEL_REQUIRED_VERSION=2.0.0 INDICATOR_REQUIRED_VERSION=0.3.19 GLIB_REQUIRED_VERSION=2.33.10 INTROSPECTION_REQUIRED_VERSION=1.32.0 -- cgit v1.2.3 From d0e1bf194504adc68a87423c74b8dbb3896be87a Mon Sep 17 00:00:00 2001 From: Sebastien Bacher Date: Tue, 21 Aug 2012 17:23:15 +0200 Subject: libmessaging-menu: fix export-symbols-regex --- libmessaging-menu/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmessaging-menu/Makefile.am b/libmessaging-menu/Makefile.am index 187e6dc..d0f941f 100644 --- a/libmessaging-menu/Makefile.am +++ b/libmessaging-menu/Makefile.am @@ -18,7 +18,7 @@ libmessaging_menu_la_CFLAGS = \ $(GIO_CFLAGS) \ -Wall -libmessaging_menu_la_LDFLAGS = -export-symbols-regex="^messaging_menu_.*" +libmessaging_menu_la_LDFLAGS = -export-symbols-regex "^messaging_menu_.*" BUILT_SOURCES = \ indicator-messages-service.c \ -- cgit v1.2.3 From 52875e80b988a7f0c5af3d4ebe720917f93c873d Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 10:37:04 +0200 Subject: libmessaging-menu: warn when desktop_id is NULL (instead of crashing) --- libmessaging-menu/messaging-menu.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index 336e89c..b8aaf20 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -74,6 +74,21 @@ static void global_status_changed (IndicatorMessagesService *service, const gchar *status_str, gpointer user_data); +static void +messaging_menu_app_set_desktop_id (MessagingMenuApp *app, + const gchar *desktop_id) +{ + g_return_if_fail (desktop_id != NULL); + + /* no need to clean up, it's construct only */ + app->appinfo = g_desktop_app_info_new (desktop_id); + if (app->appinfo == NULL) + { + g_warning ("could not find the desktop file for '%s'", + desktop_id); + } +} + static void messaging_menu_app_set_property (GObject *object, guint prop_id, @@ -85,12 +100,7 @@ messaging_menu_app_set_property (GObject *object, switch (prop_id) { case PROP_DESKTOP_ID: - app->appinfo = g_desktop_app_info_new (g_value_get_string (value)); - if (app->appinfo == NULL) - { - g_warning ("could not find the desktop file for '%s'", - g_value_get_string (value)); - } + messaging_menu_app_set_desktop_id (app, g_value_get_string (value)); break; default: -- cgit v1.2.3 From dd134484da92096b4116cdfb88c36756bf234722 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 10:41:15 +0200 Subject: libmessaging-menu: annotate icon parameters with allow-none --- libmessaging-menu/messaging-menu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index b8aaf20..78fff20 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -511,7 +511,7 @@ messaging_menu_app_insert_source (MessagingMenuApp *app, * messaging_menu_app_append_source: * @app: a #MessagingMenuApp * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * * Appends a new message source to the end of the section representing @app. @@ -535,7 +535,7 @@ messaging_menu_app_append_source (MessagingMenuApp *app, * @app: a #MessagingMenuApp * @position: the position at which to insert the source * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @count: the count for the source * @@ -563,7 +563,7 @@ messaging_menu_app_insert_source_with_count (MessagingMenuApp *app, * messaging_menu_app_append_source_with_count: * @app: a #MessagingMenuApp * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @count: the count for the source * @@ -589,7 +589,7 @@ void messaging_menu_app_append_source_with_count (MessagingMenuApp *app, * @app: a #MessagingMenuApp * @position: the position at which to insert the source * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @time: the time when the source was created * @@ -618,7 +618,7 @@ messaging_menu_app_insert_source_with_time (MessagingMenuApp *app, * @app: a #MessagingMenuApp * @position: the position at which to insert the source * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @time: the time when the source was created * @@ -645,7 +645,7 @@ messaging_menu_app_append_source_with_time (MessagingMenuApp *app, * @app: a #MessagingMenuApp * @position: the position at which to insert the source * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @str: a string associated with the source * @@ -674,7 +674,7 @@ messaging_menu_app_insert_source_with_string (MessagingMenuApp *app, * @app: a #MessagingMenuApp * @position: the position at which to insert the source * @id: a unique identifier for the source to be added - * @icon: the icon associated with the source + * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source * @str: a string associated with the source * -- cgit v1.2.3 From d519ebfb52d69765f4e1ec0aa3f115f2c04c9bb4 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 12:20:21 +0200 Subject: libmessaging-menu: remove sources when they are activated Applications shouldn't leave message sources that the user clicked on in the messaging menu. This patch spares apps from having to call remove_source in all of their handlers. --- libmessaging-menu/messaging-menu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index 78fff20..daeaeb5 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -419,6 +419,8 @@ source_action_activated (GTupleAction *action, const gchar *name = g_action_get_name (G_ACTION (action)); GQuark q = g_quark_from_string (name); + messaging_menu_app_remove_source (app, name); + g_signal_emit (app, signals[ACTIVATE_SOURCE], q, name); } -- cgit v1.2.3 From 95aa2195c3e7e5873a1508e77b8305cf92e2215b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 12:23:24 +0200 Subject: libmessaging-menu: don't warn when removing a non-existant source --- libmessaging-menu/messaging-menu.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index daeaeb5..69fb3b7 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -716,10 +716,7 @@ messaging_menu_app_remove_source (MessagingMenuApp *app, g_return_if_fail (source_id != NULL); if (g_simple_action_group_lookup (app->source_actions, source_id) == NULL) - { - g_warning ("%s: a source with id '%s' doesn't exist", G_STRFUNC, source_id); return; - } n_items = g_menu_model_get_n_items (G_MENU_MODEL (app->menu)); for (i = 0; i < n_items; i++) -- cgit v1.2.3 From 802b10555a5d2fe6bdbbe34cba873cf9dd60050e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 16:09:57 +0200 Subject: Make the panel plugin reconnect to the service when it restarts --- src/indicator-messages.c | 92 +++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 946da55..b3166f5 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -61,6 +61,7 @@ struct _IndicatorMessages { GMenu *menu_wrapper; GMenuModel *menu; GtkWidget *image; + GtkWidget *gtkmenu; gchar *accessible_desc; }; @@ -75,6 +76,9 @@ 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 void service_connection_changed (IndicatorServiceManager *sm, + gboolean connected, + gpointer user_data); static GtkImage * get_image (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); static const gchar * get_accessible_desc (IndicatorObject * io); @@ -110,40 +114,14 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) static void indicator_messages_init (IndicatorMessages *self) { - GDBusConnection *bus; - GError *error = NULL; - - /* Default values */ - self->service = NULL; - - /* Complex stuff */ self->service = indicator_service_manager_new_version(INDICATOR_MESSAGES_DBUS_NAME, 1); + g_signal_connect (self->service, "connection-change", + G_CALLBACK (service_connection_changed), 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)); - - g_signal_connect (self->menu, "items-changed", G_CALLBACK (menu_items_changed), self); + self->menu_wrapper = g_object_ref_sink (g_menu_new ()); + self->gtkmenu = gtk_menu_new_from_model (G_MENU_MODEL (self->menu_wrapper)); self->image = g_object_ref_sink (gtk_image_new ()); - gtk_widget_show (self->image); - update_root_item (self); - - self->menu_wrapper = g_menu_new (); - 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 */ @@ -162,6 +140,7 @@ indicator_messages_dispose (GObject *object) g_clear_object (&self->menu_wrapper); g_clear_object (&self->actions); g_clear_object (&self->menu); + g_clear_object (&self->gtkmenu); g_clear_object (&self->image); G_OBJECT_CLASS (indicator_messages_parent_class)->dispose (object); @@ -184,11 +163,56 @@ indicator_messages_finalize (GObject *object) /* Functions */ +static void service_connection_changed (IndicatorServiceManager *sm, + gboolean connected, + gpointer user_data) +{ + IndicatorMessages *self = user_data; + GDBusConnection *bus; + GError *error = NULL; + + g_clear_object (&self->actions); + if (self->menu != NULL) { + g_signal_handlers_disconnect_by_func (self->menu, menu_items_changed, self); + g_clear_object (&self->menu); + } + if (g_menu_model_get_n_items (G_MENU_MODEL (self->menu_wrapper)) == 1) + g_menu_remove (self->menu_wrapper, 0); + + if (connected == FALSE) + return; + + 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)); + gtk_widget_insert_action_group (self->gtkmenu, + get_name_hint (INDICATOR_OBJECT (self)), + self->actions); + + self->menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, + INDICATOR_MESSAGES_DBUS_NAME, + INDICATOR_MESSAGES_DBUS_OBJECT)); + g_signal_connect (self->menu, "items-changed", G_CALLBACK (menu_items_changed), self); + + update_root_item (self); + update_menu (self); + + g_object_unref (bus); +} + static GtkImage * get_image (IndicatorObject * io) { IndicatorMessages *self = INDICATOR_MESSAGES (io); + gtk_widget_show (self->image); return GTK_IMAGE (self->image); } @@ -196,12 +220,8 @@ static GtkMenu * get_menu (IndicatorObject * io) { IndicatorMessages *self = INDICATOR_MESSAGES (io); - 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); + return GTK_MENU (self->gtkmenu); } static const gchar * @@ -269,7 +289,7 @@ update_menu (IndicatorMessages *self) GMenuModel *popup; GMenuItem *item; - if (g_menu_model_get_n_items (self->menu) == 0) + if (self->menu == NULL || g_menu_model_get_n_items (self->menu) == 0) return; popup = g_menu_model_get_item_link (self->menu, 0, G_MENU_LINK_SUBMENU); -- cgit v1.2.3 From 423d61b377588e67cb570480828f752925371f85 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 16:31:30 +0200 Subject: libmessaging-menu: re-register with the service if it restarted --- libmessaging-menu/messaging-menu.c | 42 +++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index 69fb3b7..387412e 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -39,6 +39,7 @@ struct _MessagingMenuApp GMenu *menu; IndicatorMessagesService *messages_service; + guint watch_id; GCancellable *cancellable; }; @@ -119,6 +120,12 @@ messaging_menu_app_dispose (GObject *object) { MessagingMenuApp *app = MESSAGING_MENU_APP (object); + if (app->watch_id > 0) + { + g_bus_unwatch_name (app->watch_id); + app->watch_id = 0; + } + if (app->cancellable) { g_cancellable_cancel (app->cancellable); @@ -243,6 +250,17 @@ got_session_bus (GObject *source, g_error_free (error); } + g_object_unref (bus); +} + +static void +indicator_messages_appeared (GDBusConnection *bus, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + MessagingMenuApp *app = user_data; + indicator_messages_service_proxy_new (bus, G_DBUS_PROXY_FLAGS_NONE, "com.canonical.indicator.messages", @@ -250,8 +268,22 @@ got_session_bus (GObject *source, app->cancellable, created_messages_service, app); +} - g_object_unref (bus); +static void +indicator_messages_vanished (GDBusConnection *bus, + const gchar *name, + gpointer user_data) +{ + MessagingMenuApp *app = user_data; + + if (app->messages_service) + { + g_signal_handlers_disconnect_by_func (app->messages_service, + global_status_changed, + app); + g_clear_object (&app->messages_service); + } } static void @@ -272,6 +304,14 @@ messaging_menu_app_init (MessagingMenuApp *app) app->cancellable, got_session_bus, app); + + app->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + "com.canonical.indicator.messages", + G_BUS_NAME_WATCHER_FLAGS_NONE, + indicator_messages_appeared, + indicator_messages_vanished, + app, + NULL); } /** -- cgit v1.2.3 From 195ec17a1b7e3fc89d95d21fc463499222339a63 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 Aug 2012 22:39:19 +0200 Subject: libmessaging-menu: fix g-ir-scanner warnings Also, enable warnings by default and only include messaging-menu.[ch] in the gir. --- libmessaging-menu/Makefile.am | 4 ++-- libmessaging-menu/messaging-menu.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libmessaging-menu/Makefile.am b/libmessaging-menu/Makefile.am index d0f941f..ef37700 100644 --- a/libmessaging-menu/Makefile.am +++ b/libmessaging-menu/Makefile.am @@ -41,7 +41,7 @@ pkgconfig_DATA = messaging-menu.pc -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = -INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) +INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --warn-all INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) if HAVE_INTROSPECTION @@ -51,7 +51,7 @@ MessagingMenu_1_0_gir_NAMESPACE = MessagingMenu MessagingMenu_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 MessagingMenu_1_0_gir_CFLAGS = $(INCLUDES) $(GIO_CFLAGS) MessagingMenu_1_0_gir_LIBS = libmessaging-menu.la -MessagingMenu_1_0_gir_FILES = $(libmessaging_menu_la_SOURCES) $(libmessaging_menu_la_HEADERS) +MessagingMenu_1_0_gir_FILES = messaging-menu.c messaging-menu.h INTROSPECTION_GIRS += MessagingMenu-1.0.gir girdir = $(datadir)/gir-1.0 diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index 387412e..0d80163 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -327,7 +327,7 @@ messaging_menu_app_init (MessagingMenuApp *app) * The messaging menu will return to marking the application as not running as * soon as the returned #MessagingMenuApp is destroyed. * - * Returns: (transfer-full): a new #MessagingMenuApp + * Returns: (transfer full): a new #MessagingMenuApp */ MessagingMenuApp * messaging_menu_app_new (const gchar *desktop_id) @@ -658,7 +658,6 @@ messaging_menu_app_insert_source_with_time (MessagingMenuApp *app, /** * messaging_menu_app_append_source_with_time: * @app: a #MessagingMenuApp - * @position: the position at which to insert the source * @id: a unique identifier for the source to be added * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source @@ -714,7 +713,6 @@ messaging_menu_app_insert_source_with_string (MessagingMenuApp *app, /** * messaging_menu_app_append_source_with_string: * @app: a #MessagingMenuApp - * @position: the position at which to insert the source * @id: a unique identifier for the source to be added * @icon: (allow-none): the icon associated with the source * @label: a user-visible string best describing the source @@ -832,7 +830,7 @@ messaging_menu_app_set_source_time (MessagingMenuApp *app, * messaging_menu_app_set_source_string: * @app: a #MessagingMenuApp * @source_id: a source id - * @string: the new string for the source + * @str: the new string for the source * * Updates the string displayed next to @source_id to @str. * -- cgit v1.2.3 From 28c6d543fc310d5098edb61d506aa8383a96de6f Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 Aug 2012 11:21:00 +0200 Subject: Don't use '&' in variant format strings of g_menu_item_* calls --- libmessaging-menu/messaging-menu.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libmessaging-menu/messaging-menu.c b/libmessaging-menu/messaging-menu.c index 0d80163..b090352 100644 --- a/libmessaging-menu/messaging-menu.c +++ b/libmessaging-menu/messaging-menu.c @@ -759,14 +759,18 @@ messaging_menu_app_remove_source (MessagingMenuApp *app, n_items = g_menu_model_get_n_items (G_MENU_MODEL (app->menu)); for (i = 0; i < n_items; i++) { - const gchar *action = NULL; + gchar *action; - g_menu_model_get_item_attribute (G_MENU_MODEL (app->menu), i, - "action", "&s", &action); - if (!g_strcmp0 (action, source_id)) + if (g_menu_model_get_item_attribute (G_MENU_MODEL (app->menu), i, + "action", "s", &action)) { - g_menu_remove (app->menu, i); - break; + if (!g_strcmp0 (action, source_id)) + { + g_menu_remove (app->menu, i); + break; + } + + g_free (action); } } -- cgit v1.2.3 From 1396ab4d4d799a7d51c8ac24b39921e81c900152 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 Aug 2012 18:41:21 +0200 Subject: Request showing the chat section also when the app is not running --- src/app-section.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app-section.c b/src/app-section.c index 1574892..0487fbb 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -695,6 +695,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->source_actions; + return priv->uses_chat_status; } -- cgit v1.2.3 From 8c307acb3c043645580c7a613c85fd0a5f019d49 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 Aug 2012 18:49:03 +0200 Subject: Don't spam debug messages --- src/messages-service.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/messages-service.c b/src/messages-service.c index 407b8ba..db7a8d7 100644 --- a/src/messages-service.c +++ b/src/messages-service.c @@ -313,7 +313,6 @@ change_status_action (GSimpleAction *action, g_str_equal (status, "offline")); if (!g_action_state_equal (G_ACTION (action), value)) { - g_message ("%s", status); g_simple_action_set_state (action, value); indicator_messages_service_emit_status_changed (messages_service, status); } -- cgit v1.2.3 From 4376e3e3650b18b421b53f2d441f7e74cabb70f1 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 Aug 2012 19:11:33 +0200 Subject: Make sure the time shown in the menu is always current --- src/im-source-menu-item.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/im-source-menu-item.c b/src/im-source-menu-item.c index 269c75d..43c0afb 100644 --- a/src/im-source-menu-item.c +++ b/src/im-source-menu-item.c @@ -29,6 +29,9 @@ struct _ImSourceMenuItemPrivate GtkWidget *icon; GtkWidget *label; GtkWidget *detail; + + gint64 time; + guint timer_id; }; enum @@ -143,6 +146,19 @@ im_source_menu_item_time_span_string (gint64 timestamp) return str; } +static gboolean +im_source_menu_item_update_time (gpointer data) +{ + ImSourceMenuItem *self = data; + gchar *str; + + str = im_source_menu_item_time_span_string (self->priv->time); + gtk_label_set_text (GTK_LABEL (self->priv->detail), str); + + g_free (str); + return TRUE; +} + static gboolean im_source_menu_item_set_state (ImSourceMenuItem *self, GVariant *state) @@ -153,6 +169,12 @@ im_source_menu_item_set_state (ImSourceMenuItem *self, const gchar *str; gchar *detail; + if (priv->timer_id != 0) + { + g_source_remove (priv->timer_id); + priv->timer_id = 0; + } + g_return_val_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)")), FALSE); g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); @@ -160,7 +182,11 @@ im_source_menu_item_set_state (ImSourceMenuItem *self, if (count != 0) detail = g_strdup_printf ("%d", count); else if (time != 0) - detail = im_source_menu_item_time_span_string (time); + { + priv->time = time; + detail = im_source_menu_item_time_span_string (time); + priv->timer_id = g_timeout_add_seconds (59, im_source_menu_item_update_time, self); + } else if (str != NULL && *str) detail = collapse_whitespace (str); else @@ -275,6 +301,12 @@ im_source_menu_item_dispose (GObject *object) { ImSourceMenuItem *self = IM_SOURCE_MENU_ITEM (object); + if (self->priv->timer_id != 0) + { + g_source_remove (self->priv->timer_id); + self->priv->timer_id = 0; + } + if (self->priv->action_group) im_source_menu_item_set_action_group (self, NULL); -- cgit v1.2.3 From d79f11b267f7aebf3d306f7cf7a980a4070881a7 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 25 Aug 2012 16:11:41 +0200 Subject: Fix a memory leak and potential crash: ref_sink the widget, not the GMenu --- src/indicator-messages.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/indicator-messages.c b/src/indicator-messages.c index b3166f5..f211ff8 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -118,8 +118,9 @@ indicator_messages_init (IndicatorMessages *self) g_signal_connect (self->service, "connection-change", G_CALLBACK (service_connection_changed), self); - self->menu_wrapper = g_object_ref_sink (g_menu_new ()); + self->menu_wrapper = g_menu_new (); self->gtkmenu = gtk_menu_new_from_model (G_MENU_MODEL (self->menu_wrapper)); + g_object_ref_sink (self->gtkmenu); self->image = g_object_ref_sink (gtk_image_new ()); -- cgit v1.2.3 From ca5c4991f7815f9b5190b370bfa70c651facaf72 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 25 Aug 2012 16:38:19 +0200 Subject: Plug memory leaks: return value of g_menu_model_get_item_link is transfer full --- src/gmenuutils.c | 10 +++++++++- src/messages-service.c | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gmenuutils.c b/src/gmenuutils.c index f3ceba7..f63615b 100644 --- a/src/gmenuutils.c +++ b/src/gmenuutils.c @@ -40,7 +40,15 @@ g_menu_find_section (GMenu *menu, n_items = g_menu_model_get_n_items (model); for (i = 0; i < n_items; i++) { - if (section == g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION)) + GMenuModel *link; + gboolean found; + + link = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); + found = section == link; + + g_object_unref (link); + + if (found) return i; } diff --git a/src/messages-service.c b/src/messages-service.c index db7a8d7..31d2a5b 100644 --- a/src/messages-service.c +++ b/src/messages-service.c @@ -134,6 +134,8 @@ uses_chat_status_changed (GObject *object, if (show_chat) g_menu_insert_section (menu, 0, NULL, chat_section); } + + g_object_unref (first_section); } static AppSection * -- cgit v1.2.3 From 2e6208ec6802d1686701ad0f2a665d155a1e1e58 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 08:37:25 +0200 Subject: Remove unused #include --- src/indicator-messages.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/indicator-messages.c b/src/indicator-messages.c index f211ff8..7625aa1 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -32,7 +32,6 @@ with this program. If not, see . #include #include -#include #include #include "dbus-data.h" -- cgit v1.2.3 From 26e95dd525ecee8024bcee0e45730798e08c877a Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 09:16:57 +0200 Subject: Install icons in the standard path --- configure.ac | 3 --- data/icons/16x16/categories/Makefile.am | 2 +- data/icons/16x16/status/Makefile.am | 2 +- data/icons/22x22/categories/Makefile.am | 2 +- data/icons/22x22/status/Makefile.am | 2 +- data/icons/24x24/status/Makefile.am | 2 +- data/icons/32x32/categories/Makefile.am | 2 +- data/icons/32x32/status/Makefile.am | 2 +- data/icons/48x48/status/Makefile.am | 2 +- data/icons/scalable/categories/Makefile.am | 2 +- data/icons/scalable/status/Makefile.am | 2 +- 11 files changed, 10 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index d9270dd..08560c6 100644 --- a/configure.ac +++ b/configure.ac @@ -106,13 +106,10 @@ AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all if test "x$with_localinstall" = "xyes"; then INDICATORDIR="${libdir}/indicators/2/" - INDICATORICONSDIR="${datadir}/libindicate/icons/" else INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator3-0.4` - INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator3-0.4` fi AC_SUBST(INDICATORDIR) -AC_SUBST(INDICATORICONSDIR) ########################### # DBus Service Info diff --git a/data/icons/16x16/categories/Makefile.am b/data/icons/16x16/categories/Makefile.am index 171e2f9..2ddfa63 100644 --- a/data/icons/16x16/categories/Makefile.am +++ b/data/icons/16x16/categories/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/16x16/categories +iconsdir = $(datadir)/icons/hicolor/16x16/categories icons_DATA = \ applications-email-panel.png \ diff --git a/data/icons/16x16/status/Makefile.am b/data/icons/16x16/status/Makefile.am index e9c66f1..adafb8c 100644 --- a/data/icons/16x16/status/Makefile.am +++ b/data/icons/16x16/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/16x16/status +iconsdir = $(datadir)/icons/hicolor/16x16/status icons_DATA = \ application-running.png \ diff --git a/data/icons/22x22/categories/Makefile.am b/data/icons/22x22/categories/Makefile.am index 02885d3..b1ea14c 100644 --- a/data/icons/22x22/categories/Makefile.am +++ b/data/icons/22x22/categories/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/22x22/categories +iconsdir = $(datadir)/icons/hicolor/22x22/categories icons_DATA = \ applications-email-panel.png diff --git a/data/icons/22x22/status/Makefile.am b/data/icons/22x22/status/Makefile.am index f18bbcc..470c817 100644 --- a/data/icons/22x22/status/Makefile.am +++ b/data/icons/22x22/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/22x22/status +iconsdir = $(datadir)/icons/hicolor/22x22/status icons_DATA = \ indicator-messages.png \ diff --git a/data/icons/24x24/status/Makefile.am b/data/icons/24x24/status/Makefile.am index 7686c0e..086c404 100644 --- a/data/icons/24x24/status/Makefile.am +++ b/data/icons/24x24/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/24x24/status +iconsdir = $(datadir)/icons/hicolor/24x24/status icons_DATA = \ application-running.png \ diff --git a/data/icons/32x32/categories/Makefile.am b/data/icons/32x32/categories/Makefile.am index 3a74b80..6fcfb7b 100644 --- a/data/icons/32x32/categories/Makefile.am +++ b/data/icons/32x32/categories/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/32x32/categories +iconsdir = $(datadir)/icons/hicolor/32x32/categories icons_DATA = \ applications-email-panel.png \ diff --git a/data/icons/32x32/status/Makefile.am b/data/icons/32x32/status/Makefile.am index 84d9609..00f9d53 100644 --- a/data/icons/32x32/status/Makefile.am +++ b/data/icons/32x32/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/32x32/status +iconsdir = $(datadir)/icons/hicolor/32x32/status icons_DATA = \ application-running.png \ diff --git a/data/icons/48x48/status/Makefile.am b/data/icons/48x48/status/Makefile.am index ee7eb74..9c560b5 100644 --- a/data/icons/48x48/status/Makefile.am +++ b/data/icons/48x48/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/48x48/status +iconsdir = $(datadir)/icons/hicolor/48x48/status icons_DATA = \ application-running.png \ diff --git a/data/icons/scalable/categories/Makefile.am b/data/icons/scalable/categories/Makefile.am index 64ce622..0fdbbd7 100644 --- a/data/icons/scalable/categories/Makefile.am +++ b/data/icons/scalable/categories/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/scalable/categories +iconsdir = $(datadir)/icons/hicolor/scalable/categories icons_DATA = \ applications-email-panel.svg \ diff --git a/data/icons/scalable/status/Makefile.am b/data/icons/scalable/status/Makefile.am index 060b479..59f0256 100644 --- a/data/icons/scalable/status/Makefile.am +++ b/data/icons/scalable/status/Makefile.am @@ -1,5 +1,5 @@ -iconsdir = $(INDICATORICONSDIR)/hicolor/scalable/status +iconsdir = $(datadir)/icons/hicolor/scalable/status icons_DATA = \ application-running.svg \ -- cgit v1.2.3 From 98f03a9d7d29ba2531d098f99c7f72b844f8213e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 11:53:58 +0200 Subject: Bring back the blue icon when a source is drawing attention --- src/indicator-messages.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/indicator-messages.c b/src/indicator-messages.c index f211ff8..4f5a012 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -90,6 +90,10 @@ static void menu_items_changed (GMenuModel *menu, gint removed, gint added, gpointer user_data); +static void messages_state_changed (GActionGroup *action_group, + gchar *action_name, + GVariant *value, + gpointer user_data); G_DEFINE_TYPE (IndicatorMessages, indicator_messages, INDICATOR_OBJECT_TYPE); @@ -172,7 +176,10 @@ static void service_connection_changed (IndicatorServiceManager *sm, GDBusConnection *bus; GError *error = NULL; - g_clear_object (&self->actions); + if (self->actions != NULL) { + g_signal_handlers_disconnect_by_func (self->actions, messages_state_changed, self); + g_clear_object (&self->actions); + } if (self->menu != NULL) { g_signal_handlers_disconnect_by_func (self->menu, menu_items_changed, self); g_clear_object (&self->menu); @@ -196,6 +203,8 @@ static void service_connection_changed (IndicatorServiceManager *sm, gtk_widget_insert_action_group (self->gtkmenu, get_name_hint (INDICATOR_OBJECT (self)), self->actions); + g_signal_connect (self->actions, "action-state-changed::messages", + G_CALLBACK (messages_state_changed), self); self->menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, INDICATOR_MESSAGES_DBUS_NAME, @@ -323,3 +332,19 @@ menu_items_changed (GMenuModel *menu, update_menu (self); } } + +static void +messages_state_changed (GActionGroup *action_group, + gchar *action_name, + GVariant *value, + gpointer user_data) +{ + IndicatorMessages *self = user_data; + + g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); + + if (g_variant_get_boolean (value)) + gtk_image_set_from_icon_name (GTK_IMAGE (self->image), "indicator-messages-new", GTK_ICON_SIZE_MENU); + else + gtk_image_set_from_icon_name (GTK_IMAGE (self->image), "indicator-messages", GTK_ICON_SIZE_MENU); +} -- cgit v1.2.3 From acc4b2a7088a47ef3d7b8570f88833399dbfe783 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 12:01:13 +0200 Subject: Make sure the icon is cleared also when a source is removed The code was there, but an superfluous condition made the function return early. --- src/app-section.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/app-section.c b/src/app-section.c index 0487fbb..baae21f 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -678,16 +678,9 @@ action_removed (GActionGroup *group, 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); } gboolean -- cgit v1.2.3 From fab67a704ed6f189014a1988e641194e0f4babb1 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 15:38:04 +0200 Subject: Show icons on status menu items This introduces IdoMenuItem, a GtkCheckMenuItem that can also show icons. This should go into libido at some point. Also, Im{App,Source}MenuItem could derive from it so that the GMenuItem-setting logic is only in one place. --- src/Makefile.am | 2 + src/ido-menu-item.c | 378 +++++++++++++++++++++++++++++++++++++++++++++++ src/ido-menu-item.h | 54 +++++++ src/indicator-messages.c | 2 + src/messages-service.c | 29 +++- 5 files changed, 460 insertions(+), 5 deletions(-) create mode 100644 src/ido-menu-item.c create mode 100644 src/ido-menu-item.h diff --git a/src/Makefile.am b/src/Makefile.am index 403a289..4d86730 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,6 +15,8 @@ messaginglibdir = $(INDICATORDIR) messaginglib_LTLIBRARIES = libmessaging.la libmessaging_la_SOURCES = \ indicator-messages.c \ + ido-menu-item.c \ + ido-menu-item.h \ im-app-menu-item.c \ im-app-menu-item.h \ im-source-menu-item.c \ diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c new file mode 100644 index 0000000..391f0df --- /dev/null +++ b/src/ido-menu-item.c @@ -0,0 +1,378 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * 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 . + * + * Authors: + * Lars Uebernickel + */ + +#include "ido-menu-item.h" + +struct _IdoMenuItemPrivate +{ + GActionGroup *action_group; + gchar *action; + GVariant *target; + + GtkWidget *icon; + GtkWidget *label; + + gboolean has_indicator; + gboolean in_set_active; +}; + +enum +{ + PROP_0, + PROP_MENU_ITEM, + PROP_ACTION_GROUP, + NUM_PROPERTIES +}; + +static GParamSpec *properties[NUM_PROPERTIES]; + +G_DEFINE_TYPE (IdoMenuItem, ido_menu_item, GTK_TYPE_CHECK_MENU_ITEM); + +static void +ido_menu_item_constructed (GObject *object) +{ + IdoMenuItemPrivate *priv = IDO_MENU_ITEM (object)->priv; + GtkWidget *grid; + + priv->icon = g_object_ref (gtk_image_new ()); + + priv->label = g_object_ref (gtk_label_new ("")); + + grid = gtk_grid_new (); + gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1); + + gtk_container_add (GTK_CONTAINER (object), grid); + gtk_widget_show_all (grid); + + G_OBJECT_CLASS (ido_menu_item_parent_class)->constructed (object); +} + +static void +ido_menu_item_set_active (IdoMenuItem *self, + gboolean active) +{ + /* HACK gtk_check_menu_item_set_active calls gtk_menu_item_activate. + * Make sure our activate handler doesn't toggle the action as a + * result of calling this function. */ + + self->priv->in_set_active = TRUE; + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (self), active); + self->priv->in_set_active = FALSE; +} + +static void +ido_menu_item_set_has_indicator (IdoMenuItem *self, + gboolean has_indicator) +{ + if (has_indicator == self->priv->has_indicator) + return; + + self->priv->has_indicator = has_indicator; + + gtk_widget_queue_resize (GTK_WIDGET (self)); +} + +static void +ido_menu_item_set_state (IdoMenuItem *self, + GVariant *state) +{ + IdoMenuItemPrivate *priv = self->priv; + + if (priv->target) + { + ido_menu_item_set_has_indicator (self, TRUE); + gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (self), TRUE); + ido_menu_item_set_active (self, g_variant_equal (priv->target, state)); + } + else if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN)) + { + ido_menu_item_set_has_indicator (self, TRUE); + gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (self), FALSE); + ido_menu_item_set_active (self, g_variant_get_boolean (state)); + } + else + { + ido_menu_item_set_has_indicator (self, FALSE); + } +} + +static void +ido_menu_item_set_action_name (IdoMenuItem *self, + const gchar *action_name) +{ + IdoMenuItemPrivate *priv = self->priv; + gboolean enabled = FALSE; + GVariant *state; + const GVariantType *param_type; + + if (priv->action != NULL) + g_free (priv->action); + + priv->action = g_strdup (action_name); + + if (priv->action_group != NULL && priv->action != NULL && + g_action_group_query_action (priv->action_group, priv->action, + &enabled, ¶m_type, NULL, NULL, &state)) + { + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); + ido_menu_item_set_state (self, state); + + if (state) + g_variant_unref (state); + } + else + { + ido_menu_item_set_active (self, FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + ido_menu_item_set_has_indicator (self, FALSE); + } +} + +static void +ido_menu_item_action_added (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + IdoMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + ido_menu_item_set_action_name (self, action_name); +} + +static void +ido_menu_item_action_removed (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + IdoMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + { + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + } +} + +static void +ido_menu_item_action_enabled_changed (GActionGroup *action_group, + gchar *action_name, + gboolean enabled, + gpointer user_data) +{ + IdoMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); +} + +static void +ido_menu_item_action_state_changed (GActionGroup *action_group, + gchar *action_name, + GVariant *value, + gpointer user_data) +{ + IdoMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + ido_menu_item_set_state (self, value); +} + +static void +ido_menu_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + IdoMenuItem *self = IDO_MENU_ITEM (object); + + switch (property_id) + { + case PROP_MENU_ITEM: + ido_menu_item_set_menu_item (self, G_MENU_ITEM (g_value_get_object (value))); + break; + + case PROP_ACTION_GROUP: + ido_menu_item_set_action_group (self, G_ACTION_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +ido_menu_item_dispose (GObject *object) +{ + IdoMenuItem *self = IDO_MENU_ITEM (object); + + if (self->priv->action_group) + ido_menu_item_set_action_group (self, NULL); + + g_clear_object (&self->priv->icon); + g_clear_object (&self->priv->label); + + if (self->priv->target) + g_variant_unref (self->priv->target); + + G_OBJECT_CLASS (ido_menu_item_parent_class)->dispose (object); +} + +static void +ido_menu_item_finalize (GObject *object) +{ + IdoMenuItemPrivate *priv = IDO_MENU_ITEM (object)->priv; + + g_free (priv->action); + + G_OBJECT_CLASS (ido_menu_item_parent_class)->finalize (object); +} + +static void +ido_menu_item_activate (GtkMenuItem *item) +{ + IdoMenuItemPrivate *priv = IDO_MENU_ITEM (item)->priv; + + /* see ido_menu_item_set_active */ + if (!priv->in_set_active && priv->action && priv->action_group) + g_action_group_activate_action (priv->action_group, priv->action, priv->target); + + GTK_MENU_ITEM_CLASS (ido_menu_item_parent_class)->activate (item); +} + +static void +ido_menu_item_draw_indicator (GtkCheckMenuItem *item, + cairo_t *cr) +{ + IdoMenuItem *self = IDO_MENU_ITEM (item); + + if (self->priv->has_indicator) + GTK_CHECK_MENU_ITEM_CLASS (ido_menu_item_parent_class) + ->draw_indicator (item, cr); +} + +static void +ido_menu_item_class_init (IdoMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS (klass); + GtkCheckMenuItemClass *check_class = GTK_CHECK_MENU_ITEM_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IdoMenuItemPrivate)); + + object_class->constructed = ido_menu_item_constructed; + object_class->set_property = ido_menu_set_property; + object_class->dispose = ido_menu_item_dispose; + object_class->finalize = ido_menu_item_finalize; + + menu_item_class->activate = ido_menu_item_activate; + + check_class->draw_indicator = ido_menu_item_draw_indicator; + + properties[PROP_MENU_ITEM] = g_param_spec_object ("menu-item", + "Menu item", + "The model GMenuItem for this menu item", + G_TYPE_MENU_ITEM, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ACTION_GROUP] = g_param_spec_object ("action-group", + "Action group", + "The action group associated with this menu item", + G_TYPE_ACTION_GROUP, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); +} + +static void +ido_menu_item_init (IdoMenuItem *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IDO_TYPE_MENU_ITEM, + IdoMenuItemPrivate); +} + +void +ido_menu_item_set_menu_item (IdoMenuItem *self, + GMenuItem *menuitem) +{ + gchar *iconstr = NULL; + GIcon *icon = NULL; + gchar *label; + gchar *action = NULL; + + if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr)) + { + GError *error; + + icon = g_icon_new_for_string (iconstr, &error); + if (icon == NULL) + { + g_warning ("unable to set icon: %s", error->message); + g_error_free (error); + } + g_free (iconstr); + } + gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU); + + g_menu_item_get_attribute (menuitem, "label", "s", &label); + gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : ""); + + self->priv->target = g_menu_item_get_attribute_value (menuitem, "target", NULL); + + g_menu_item_get_attribute (menuitem, "action", "s", &action); + ido_menu_item_set_action_name (self, action); + + if (icon) + g_object_unref (icon); + g_free (label); + g_free (action); +} + +void +ido_menu_item_set_action_group (IdoMenuItem *self, + GActionGroup *action_group) +{ + IdoMenuItemPrivate *priv = self->priv; + + if (priv->action_group != NULL) + { + g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_added, self); + g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_removed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_enabled_changed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_state_changed, self); + + g_clear_object (&priv->action_group); + } + + if (action_group != NULL) + { + priv->action_group = g_object_ref (action_group); + + g_signal_connect (priv->action_group, "action-added", + G_CALLBACK (ido_menu_item_action_added), self); + g_signal_connect (priv->action_group, "action-removed", + G_CALLBACK (ido_menu_item_action_removed), self); + g_signal_connect (priv->action_group, "action-enabled-changed", + G_CALLBACK (ido_menu_item_action_enabled_changed), self); + g_signal_connect (priv->action_group, "action-state-changed", + G_CALLBACK (ido_menu_item_action_state_changed), self); + } +} diff --git a/src/ido-menu-item.h b/src/ido-menu-item.h new file mode 100644 index 0000000..0521928 --- /dev/null +++ b/src/ido-menu-item.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * 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 . + * + * Authors: + * Lars Uebernickel + */ + +#ifndef __IDO_MENU_ITEM_H__ +#define __IDO_MENU_ITEM_H__ + +#include + +#define IDO_TYPE_MENU_ITEM (ido_menu_item_get_type ()) +#define IDO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_MENU_ITEM, IdoMenuItem)) +#define IDO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IDO_TYPE_MENU_ITEM, IdoMenuItemClass)) +#define IS_IDO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_MENU_ITEM)) +#define IS_IDO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IDO_TYPE_MENU_ITEM)) +#define IDO_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IDO_TYPE_MENU_ITEM, IdoMenuItemClass)) + +typedef struct _IdoMenuItem IdoMenuItem; +typedef struct _IdoMenuItemClass IdoMenuItemClass; +typedef struct _IdoMenuItemPrivate IdoMenuItemPrivate; + +struct _IdoMenuItemClass +{ + GtkCheckMenuItemClass parent_class; +}; + +struct _IdoMenuItem +{ + GtkCheckMenuItem parent; + IdoMenuItemPrivate *priv; +}; + +GType ido_menu_item_get_type (void); + +void ido_menu_item_set_menu_item (IdoMenuItem *item, + GMenuItem *menuitem); +void ido_menu_item_set_action_group (IdoMenuItem *self, + GActionGroup *action_group); + +#endif diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 7625aa1..714a962 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -36,6 +36,7 @@ with this program. If not, see . #include "dbus-data.h" +#include "ido-menu-item.h" #include "im-app-menu-item.h" #include "im-source-menu-item.h" @@ -125,6 +126,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 */ + ido_menu_item_get_type (); im_app_menu_item_get_type (); im_source_menu_item_get_type (); } diff --git a/src/messages-service.c b/src/messages-service.c index 31d2a5b..15c5123 100644 --- a/src/messages-service.c +++ b/src/messages-service.c @@ -406,14 +406,33 @@ static GMenuModel * create_status_section (void) { GMenu *menu; + GMenuItem *item; + struct status_item { + gchar *label; + gchar *action; + gchar *icon_name; + } status_items[] = { + { _("Available"), "status::available", "user-available" }, + { _("Away"), "status::away", "user-away" }, + { _("Busy"), "status::busy", "user-busy" }, + { _("Invisible"), "status::invisible", "user-invisible" }, + { _("Offline"), "status::offline", "user-offline" } + }; + int i; menu = g_menu_new (); - g_menu_append_with_icon_name (menu, _("Available"), "user-available", "status::available"); - g_menu_append_with_icon_name (menu, _("Away"), "user-away", "status::away"); - g_menu_append_with_icon_name (menu, _("Busy"), "user-busy", "status::busy"); - g_menu_append_with_icon_name (menu, _("Invisible"), "user-invisible", "status::invisible"); - g_menu_append_with_icon_name (menu, _("Offline"), "user-offline", "status::offline"); + item = g_menu_item_new (NULL, NULL); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "IdoMenuItem"); + + for (i = 0; i < G_N_ELEMENTS (status_items); i++) { + g_menu_item_set_label (item, status_items[i].label); + g_menu_item_set_detailed_action (item, status_items[i].action); + g_menu_item_set_attribute (item, "x-canonical-icon", "s", status_items[i].icon_name); + g_menu_append_item (menu, item); + } + + g_object_unref (item); return G_MENU_MODEL (menu); } -- cgit v1.2.3 From 5c88df7dcff3fcb98507a9b1c073bb5b23e1487d Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 16:13:36 +0200 Subject: IdoMenuItem: don't try to set state on stateless actions --- src/app-section.c | 7 ++++++- src/ido-menu-item.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/app-section.c b/src/app-section.c index 0487fbb..d4bc3dd 100644 --- a/src/app-section.c +++ b/src/app-section.c @@ -346,6 +346,7 @@ 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]); @@ -354,8 +355,12 @@ app_section_set_app_info (AppSection *self, g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); g_object_unref (action); - g_menu_append (priv->menu, name, nicks[i]); + item = g_menu_item_new (name, nicks[i]); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "IdoMenuItem"); + g_menu_item_set_attribute (item, "x-canonical-icon", "s", ""); /* empty to get indentation */ + g_menu_append_item (priv->menu, item); + g_object_unref (item); g_free(name); } diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c index 391f0df..c2a8309 100644 --- a/src/ido-menu-item.c +++ b/src/ido-menu-item.c @@ -132,10 +132,12 @@ ido_menu_item_set_action_name (IdoMenuItem *self, &enabled, ¶m_type, NULL, NULL, &state)) { gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); - ido_menu_item_set_state (self, state); if (state) - g_variant_unref (state); + { + ido_menu_item_set_state (self, state); + g_variant_unref (state); + } } else { -- cgit v1.2.3 From 29252e90c642281aeaae41640acd6db450383624 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 16:34:16 +0200 Subject: Indent application shortcuts This is done by setting their icon to the empty string, which IdoMenuItem interprets as "show a clear icon". --- src/ido-menu-item.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c index c2a8309..306d846 100644 --- a/src/ido-menu-item.c +++ b/src/ido-menu-item.c @@ -324,11 +324,22 @@ ido_menu_item_set_menu_item (IdoMenuItem *self, { GError *error; - icon = g_icon_new_for_string (iconstr, &error); - if (icon == NULL) + /* only indent the label if icon is set to "" */ + if (iconstr[0] == '\0') { - g_warning ("unable to set icon: %s", error->message); - g_error_free (error); + gint width; + + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL); + gtk_widget_set_size_request (self->priv->icon, width, -1); + } + else + { + icon = g_icon_new_for_string (iconstr, &error); + if (icon == NULL) + { + g_warning ("unable to set icon: %s", error->message); + g_error_free (error); + } } g_free (iconstr); } -- cgit v1.2.3 From c3bbc027e18bf05520b7a94127da20338855c535 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 16:42:05 +0200 Subject: Increase spacing between icons and labels --- src/ido-menu-item.c | 1 + src/im-app-menu-item.c | 1 + src/im-source-menu-item.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c index 306d846..9700b1a 100644 --- a/src/ido-menu-item.c +++ b/src/ido-menu-item.c @@ -51,6 +51,7 @@ ido_menu_item_constructed (GObject *object) GtkWidget *grid; priv->icon = g_object_ref (gtk_image_new ()); + gtk_widget_set_margin_right (priv->icon, 6); priv->label = g_object_ref (gtk_label_new ("")); diff --git a/src/im-app-menu-item.c b/src/im-app-menu-item.c index eddf562..a204631 100644 --- a/src/im-app-menu-item.c +++ b/src/im-app-menu-item.c @@ -48,6 +48,7 @@ im_app_menu_item_constructed (GObject *object) GtkWidget *grid; priv->icon = g_object_ref (gtk_image_new ()); + gtk_widget_set_margin_right (priv->icon, 6); priv->label = g_object_ref (gtk_label_new ("")); diff --git a/src/im-source-menu-item.c b/src/im-source-menu-item.c index 43c0afb..5aebb68 100644 --- a/src/im-source-menu-item.c +++ b/src/im-source-menu-item.c @@ -56,7 +56,7 @@ im_source_menu_item_constructed (GObject *object) gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL); priv->icon = g_object_ref (gtk_image_new ()); - gtk_widget_set_margin_left (priv->icon, icon_width + 2); + gtk_widget_set_margin_left (priv->icon, icon_width + 6); priv->label = g_object_ref (gtk_label_new ("")); -- cgit v1.2.3 From 99373eb1ab1ce5aa293857625ccbe53211cd38ee Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 17:22:53 +0200 Subject: IdoMenuItem: clear target pointer in dispose --- src/ido-menu-item.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c index 9700b1a..cee032f 100644 --- a/src/ido-menu-item.c +++ b/src/ido-menu-item.c @@ -231,7 +231,10 @@ ido_menu_item_dispose (GObject *object) g_clear_object (&self->priv->label); if (self->priv->target) - g_variant_unref (self->priv->target); + { + g_variant_unref (self->priv->target); + self->priv->target = NULL; + } G_OBJECT_CLASS (ido_menu_item_parent_class)->dispose (object); } -- cgit v1.2.3 From 90fdd58aafdc8e8d8f2537acf2c1800a76a8378e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 17:30:22 +0200 Subject: ido_menu_item_set_menu_item: make sure g_free isn't called with dangling pointer --- src/ido-menu-item.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ido-menu-item.c b/src/ido-menu-item.c index cee032f..6b19d2a 100644 --- a/src/ido-menu-item.c +++ b/src/ido-menu-item.c @@ -321,7 +321,7 @@ ido_menu_item_set_menu_item (IdoMenuItem *self, { gchar *iconstr = NULL; GIcon *icon = NULL; - gchar *label; + gchar *label = NULL; gchar *action = NULL; if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr)) -- cgit v1.2.3 From abda3b07fce605d8de1c182e1dfc7569ed681f3e Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 27 Aug 2012 17:50:26 +0200 Subject: 12.10.1 --- NEWS | 9 +++++++++ configure.ac | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e69de29..95444fd 100644 --- a/NEWS +++ b/NEWS @@ -0,0 +1,9 @@ +Overview of changes from 12.10.0 to 12.10.1 +=========================================== + +* presence icons are shown again +* the icon is changed when a source draws attention +* the time in source menu items is always kep current +* fixed all g-ir-scanner warnings +* libmessaging-menu now removes sources when they are activated +* fixed several bugs diff --git a/configure.ac b/configure.ac index 08560c6..4d3ef7a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ -AC_INIT(indicator-messages, 12.10.0) +AC_INIT(indicator-messages, 12.10.1) AC_PREREQ(2.62) -- cgit v1.2.3