aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am31
-rw-r--r--src/app-menu-item.c4
-rw-r--r--src/dbus-data.h11
-rw-r--r--src/im-menu-item.c2
-rw-r--r--src/indicator-messages.c142
-rw-r--r--src/launcher-menu-item.c34
-rw-r--r--src/launcher-menu-item.h1
-rw-r--r--src/messages-service-dbus.c184
-rw-r--r--src/messages-service-dbus.h62
-rw-r--r--src/messages-service.c61
-rw-r--r--src/messages-service.xml25
11 files changed, 529 insertions, 28 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0678537..38787a1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,8 @@ bin_PROGRAMS = indicator-messages-service
messaginglibdir = $(INDICATORDIR)
messaginglib_LTLIBRARIES = libmessaging.la
libmessaging_la_SOURCES = \
- indicator-messages.c\
+ indicator-messages.c \
+ messages-service-client.h \
dbus-data.h
libmessaging_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Wl,-Bsymbolic-functions -Wl,-z,defs -Wl,--as-needed -Werror
libmessaging_la_LIBADD = $(APPLET_LIBS)
@@ -20,6 +21,9 @@ libmessaging_la_LDFLAGS = -module -avoid-version
indicator_messages_service_SOURCES = \
messages-service.c \
+ messages-service-server.h \
+ messages-service-dbus.c \
+ messages-service-dbus.h \
im-menu-item.c \
im-menu-item.h \
app-menu-item.c \
@@ -30,3 +34,28 @@ indicator_messages_service_SOURCES = \
dbus-data.h
indicator_messages_service_CFLAGS = $(APPLET_CFLAGS) -Wall -Wl,-Bsymbolic-functions -Wl,-z,defs -Wl,--as-needed -Werror
indicator_messages_service_LDADD = $(APPLET_LIBS)
+
+messages-service-client.h: $(srcdir)/messages-service.xml
+ dbus-binding-tool \
+ --prefix=_messages_service_client \
+ --mode=glib-client \
+ --output=messages-service-client.h \
+ $(srcdir)/messages-service.xml
+
+messages-service-server.h: $(srcdir)/messages-service.xml
+ dbus-binding-tool \
+ --prefix=_messages_service_server \
+ --mode=glib-server \
+ --output=messages-service-server.h \
+ $(srcdir)/messages-service.xml
+
+BUILT_SOURCES = \
+ messages-service-client.h \
+ messages-service-server.h
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ messages-service.xml
+
diff --git a/src/app-menu-item.c b/src/app-menu-item.c
index 3a2c795..feb780d 100644
--- a/src/app-menu-item.c
+++ b/src/app-menu-item.c
@@ -218,10 +218,10 @@ update_label (AppMenuItem * self)
/* TRANSLATORS: This is the name of the program and the number of indicators. So it
would read something like "Mail Client (5)" */
gchar * label = g_strdup_printf(_("%s (%d)"), app_menu_item_get_name(self), priv->unreadcount);
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "label", label);
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, label);
g_free(label);
} else {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "label", app_menu_item_get_name(self));
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, app_menu_item_get_name(self));
}
return;
diff --git a/src/dbus-data.h b/src/dbus-data.h
index 4aeedf0..db59003 100644
--- a/src/dbus-data.h
+++ b/src/dbus-data.h
@@ -2,7 +2,14 @@
#ifndef __DBUS_DATA_H__
#define __DBUS_DATA_H__ 1
-#define INDICATOR_MESSAGES_DBUS_NAME "com.ubuntu.indicator.messages"
-#define INDICATOR_MESSAGES_DBUS_OBJECT "/com/ubuntu/indicator/messages"
+#define INDICATOR_MESSAGES_DBUS_NAME "org.ayatana.indicator.messages"
+#define INDICATOR_MESSAGES_DBUS_OBJECT "/org/ayatana/indicator/messages/menu"
+
+#define INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT "/org/ayatana/indicator/messages/service"
+#define INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "org.ayatana.indicator.messages.service"
+
+#define LAUNCHER_MENUITEM_TYPE "launcher-item"
+#define LAUNCHER_MENUITEM_PROP_APP_NAME "application-name"
+#define LAUNCHER_MENUITEM_PROP_APP_DESC "application-description"
#endif /* __DBUS_DATA_H__ */
diff --git a/src/im-menu-item.c b/src/im-menu-item.c
index d35684e..008e33f 100644
--- a/src/im-menu-item.c
+++ b/src/im-menu-item.c
@@ -253,7 +253,7 @@ sender_cb (IndicateListener * listener, IndicateListenerServer * server, Indicat
return;
}
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "label", propertydata);
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, propertydata);
return;
}
diff --git a/src/indicator-messages.c b/src/indicator-messages.c
index efb52b2..0a1002d 100644
--- a/src/indicator-messages.c
+++ b/src/indicator-messages.c
@@ -21,6 +21,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
+#include <glib.h>
#include <gtk/gtk.h>
#include <libdbusmenu-gtk/menu.h>
#include <dbus/dbus-glib.h>
@@ -31,12 +32,140 @@ INDICATOR_SET_VERSION
INDICATOR_SET_NAME("messages")
#include "dbus-data.h"
+#include "messages-service-client.h"
-static GtkWidget * main_image;
+static GtkWidget * main_image = NULL;
#define DESIGN_TEAM_SIZE design_team_size
static GtkIconSize design_team_size;
+static DBusGProxy * icon_proxy = NULL;
+
+static void
+attention_changed_cb (DBusGProxy * proxy, gboolean dot, gpointer userdata)
+{
+ if (dot) {
+ gtk_image_set_from_icon_name(GTK_IMAGE(main_image), "indicator-messages-new", DESIGN_TEAM_SIZE);
+ } else {
+ gtk_image_set_from_icon_name(GTK_IMAGE(main_image), "indicator-messages", DESIGN_TEAM_SIZE);
+ }
+ return;
+}
+
+static void
+icon_changed_cb (DBusGProxy * proxy, gboolean hidden, gpointer userdata)
+{
+ if (hidden) {
+ gtk_widget_hide(main_image);
+ } else {
+ gtk_widget_show(main_image);
+ }
+ return;
+}
+
+static void
+watch_cb (DBusGProxy * proxy, GError * error, gpointer userdata)
+{
+ if (error != NULL) {
+ g_warning("Watch failed! %s", error->message);
+ g_error_free(error);
+ }
+ return;
+}
+
+static void
+attention_cb (DBusGProxy * proxy, gboolean dot, GError * error, gpointer userdata)
+{
+ if (error != NULL) {
+ g_warning("Unable to get attention status: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ return attention_changed_cb(proxy, dot, userdata);
+}
+
+static void
+icon_cb (DBusGProxy * proxy, gboolean hidden, GError * error, gpointer userdata)
+{
+ if (error != NULL) {
+ g_warning("Unable to get icon visibility: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ return icon_changed_cb(proxy, hidden, userdata);
+}
+
+static gboolean
+setup_icon_proxy (gpointer userdata)
+{
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ if (connection == NULL) {
+ g_warning("Unable to get session bus");
+ return FALSE; /* TRUE? */
+ }
+
+ icon_proxy = dbus_g_proxy_new_for_name(connection,
+ INDICATOR_MESSAGES_DBUS_NAME,
+ INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT,
+ INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE);
+ if (icon_proxy == NULL) {
+ g_warning("Unable to get messages service interface.");
+ return FALSE;
+ }
+
+ org_ayatana_indicator_messages_service_watch_async(icon_proxy, watch_cb, NULL);
+
+ dbus_g_proxy_add_signal(icon_proxy, "AttentionChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(icon_proxy,
+ "AttentionChanged",
+ G_CALLBACK(attention_changed_cb),
+ NULL,
+ NULL);
+
+ dbus_g_proxy_add_signal(icon_proxy, "IconChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(icon_proxy,
+ "IconChanged",
+ G_CALLBACK(icon_changed_cb),
+ NULL,
+ NULL);
+
+ org_ayatana_indicator_messages_service_attention_requested_async(icon_proxy, attention_cb, NULL);
+ org_ayatana_indicator_messages_service_icon_shown_async(icon_proxy, icon_cb, NULL);
+
+ return FALSE;
+}
+
+static gboolean
+new_launcher_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
+{
+ GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
+
+ GtkWidget * vbox = gtk_vbox_new(TRUE, 2);
+
+ GtkWidget * app_label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, LAUNCHER_MENUITEM_PROP_APP_NAME));
+ gtk_misc_set_alignment(GTK_MISC(app_label), 0.0, 0.5);
+ GtkWidget * dsc_label = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(dsc_label), 0.05, 0.5);
+ gtk_label_set_ellipsize(GTK_LABEL(dsc_label), PANGO_ELLIPSIZE_END);
+ gchar * markup = g_markup_printf_escaped("<span font-size=\"smaller\">%s</span>", dbusmenu_menuitem_property_get(newitem, LAUNCHER_MENUITEM_PROP_APP_DESC));
+ gtk_label_set_markup(GTK_LABEL(dsc_label), markup);
+ g_free(markup);
+
+ gtk_box_pack_start(GTK_BOX(vbox), app_label, FALSE, FALSE, 0);
+ gtk_widget_show(app_label);
+ gtk_box_pack_start(GTK_BOX(vbox), dsc_label, FALSE, FALSE, 0);
+ gtk_widget_show(dsc_label);
+
+ gtk_container_add(GTK_CONTAINER(gmi), GTK_WIDGET(vbox));
+ gtk_widget_show(GTK_WIDGET(vbox));
+
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+
+ return TRUE;
+}
+
GtkLabel *
get_label (void)
{
@@ -51,8 +180,6 @@ get_icon (void)
main_image = gtk_image_new_from_icon_name("indicator-messages", DESIGN_TEAM_SIZE);
gtk_widget_show(main_image);
- /* Need a proxy here to figure out when the icon changes */
-
return GTK_IMAGE(main_image);
}
@@ -76,6 +203,13 @@ get_menu (void)
return NULL;
}
- return GTK_MENU(dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT));
+ g_idle_add(setup_icon_proxy, NULL);
+
+ DbusmenuGtkMenu * menu = dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT);
+ DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu);
+
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), LAUNCHER_MENUITEM_TYPE, new_launcher_item);
+
+ return GTK_MENU(menu);
}
diff --git a/src/launcher-menu-item.c b/src/launcher-menu-item.c
index 6f005e9..822196b 100644
--- a/src/launcher-menu-item.c
+++ b/src/launcher-menu-item.c
@@ -28,6 +28,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <glib/gi18n.h>
#include <gio/gdesktopappinfo.h>
#include "launcher-menu-item.h"
+#include "dbus-data.h"
enum {
NAME_CHANGED,
@@ -130,7 +131,9 @@ launcher_menu_item_new (const gchar * desktop_file)
priv->desktop = g_strdup(desktop_file);
g_debug("\tName: %s", launcher_menu_item_get_name(self));
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "label", launcher_menu_item_get_name(self));
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "type", LAUNCHER_MENUITEM_TYPE);
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), LAUNCHER_MENUITEM_PROP_APP_NAME, launcher_menu_item_get_name(self));
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), LAUNCHER_MENUITEM_PROP_APP_DESC, launcher_menu_item_get_description(self));
g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL);
@@ -157,23 +160,12 @@ activate_cb (LauncherMenuItem * self, gpointer data)
LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self);
g_return_if_fail(priv->appinfo != NULL);
- /* This should manage the X stuff for us */
- GdkAppLaunchContext * context = gdk_app_launch_context_new();
-
- /* Using the current time as we don't have the event
- time as that's not sent across the bus */
- GTimeVal time;
- g_get_current_time(&time);
- gdk_app_launch_context_set_timestamp(context, time.tv_usec / 1000);
-
GError * error = NULL;
- if (!g_app_info_launch(priv->appinfo, NULL, G_APP_LAUNCH_CONTEXT(context), &error)) {
+ if (!g_app_info_launch(priv->appinfo, NULL, NULL, &error)) {
g_warning("Application failed to launch '%s' because: %s", launcher_menu_item_get_name(self), error->message);
g_error_free(error);
}
- g_object_unref(G_OBJECT(context));
-
return;
}
@@ -201,6 +193,20 @@ void
launcher_menu_item_set_eclipsed (LauncherMenuItem * li, gboolean eclipsed)
{
g_debug("Laucher '%s' is %s", launcher_menu_item_get_name(li), eclipsed ? "now eclipsed" : "shown again");
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li), "show", eclipsed ? "false" : "true");
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_VISIBLE, eclipsed ? "false" : "true");
return;
}
+
+gboolean
+launcher_menu_item_get_eclipsed (LauncherMenuItem * li)
+{
+ const gchar * show = dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_VISIBLE);
+ if (show == NULL) {
+ return FALSE;
+ }
+ g_debug("Launcher check eclipse: %s", show);
+ if (!g_strcmp0(show, "false")) {
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/src/launcher-menu-item.h b/src/launcher-menu-item.h
index 9a46824..3e031d5 100644
--- a/src/launcher-menu-item.h
+++ b/src/launcher-menu-item.h
@@ -58,6 +58,7 @@ const gchar * launcher_menu_item_get_name (LauncherMenuItem * appitem);
const gchar * launcher_menu_item_get_desktop (LauncherMenuItem * launchitem);
const gchar * launcher_menu_item_get_description (LauncherMenuItem * li);
void launcher_menu_item_set_eclipsed (LauncherMenuItem * li, gboolean eclipsed);
+gboolean launcher_menu_item_get_eclipsed (LauncherMenuItem * li);
G_END_DECLS
diff --git a/src/messages-service-dbus.c b/src/messages-service-dbus.c
new file mode 100644
index 0000000..d9c0e8d
--- /dev/null
+++ b/src/messages-service-dbus.c
@@ -0,0 +1,184 @@
+/*
+An indicator to show information that is in messaging applications
+that the user is using.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dbus/dbus-glib.h>
+#include "messages-service-dbus.h"
+#include "dbus-data.h"
+
+enum {
+ ATTENTION_CHANGED,
+ ICON_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct _MessageServiceDbusPrivate MessageServiceDbusPrivate;
+
+struct _MessageServiceDbusPrivate
+{
+ gboolean dot;
+ gboolean hidden;
+};
+
+#define MESSAGE_SERVICE_DBUS_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusPrivate))
+
+static void message_service_dbus_class_init (MessageServiceDbusClass *klass);
+static void message_service_dbus_init (MessageServiceDbus *self);
+static void message_service_dbus_dispose (GObject *object);
+static void message_service_dbus_finalize (GObject *object);
+
+static void _messages_service_server_watch (void);
+static gboolean _messages_service_server_attention_requested (MessageServiceDbus * self, gboolean * dot, GError ** error);
+static gboolean _messages_service_server_icon_shown (MessageServiceDbus * self, gboolean * hidden, GError ** error);
+
+#include "messages-service-server.h"
+
+G_DEFINE_TYPE (MessageServiceDbus, message_service_dbus, G_TYPE_OBJECT);
+
+static void
+message_service_dbus_class_init (MessageServiceDbusClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (MessageServiceDbusPrivate));
+
+ object_class->dispose = message_service_dbus_dispose;
+ object_class->finalize = message_service_dbus_finalize;
+
+ signals[ATTENTION_CHANGED] = g_signal_new(MESSAGE_SERVICE_DBUS_SIGNAL_ATTENTION_CHANGED,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MessageServiceDbusClass, attention_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[ICON_CHANGED] = g_signal_new(MESSAGE_SERVICE_DBUS_SIGNAL_ICON_CHANGED,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MessageServiceDbusClass, icon_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+
+ dbus_g_object_type_install_info(MESSAGE_SERVICE_DBUS_TYPE, &dbus_glib__messages_service_server_object_info);
+
+ return;
+}
+
+static void
+message_service_dbus_init (MessageServiceDbus *self)
+{
+ DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+ dbus_g_connection_register_g_object(connection,
+ INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT,
+ G_OBJECT(self));
+
+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
+
+ priv->dot = FALSE;
+ priv->hidden = FALSE;
+
+ return;
+}
+
+static void
+message_service_dbus_dispose (GObject *object)
+{
+
+
+ G_OBJECT_CLASS (message_service_dbus_parent_class)->dispose (object);
+ return;
+}
+
+static void
+message_service_dbus_finalize (GObject *object)
+{
+
+
+ G_OBJECT_CLASS (message_service_dbus_parent_class)->finalize (object);
+ return;
+}
+
+MessageServiceDbus *
+message_service_dbus_new (void)
+{
+ return MESSAGE_SERVICE_DBUS(g_object_new(MESSAGE_SERVICE_DBUS_TYPE, NULL));
+}
+
+/* DBus function to say that someone is watching */
+static void
+_messages_service_server_watch (void)
+{
+
+}
+
+/* DBus interface to request the private variable to know
+ whether there is a green dot. */
+static gboolean
+_messages_service_server_attention_requested (MessageServiceDbus * self, gboolean * dot, GError ** error)
+{
+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
+ *dot = priv->dot;
+ return TRUE;
+}
+
+/* DBus interface to request the private variable to know
+ whether the icon is hidden. */
+static gboolean
+_messages_service_server_icon_shown (MessageServiceDbus * self, gboolean * hidden, GError ** error)
+{
+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
+ *hidden = priv->hidden;
+ return TRUE;
+}
+
+void
+message_service_dbus_set_attention (MessageServiceDbus * self, gboolean attention)
+{
+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
+ /* Do signal */
+ if (attention != priv->dot) {
+ priv->dot = attention;
+ g_signal_emit(G_OBJECT(self), signals[ATTENTION_CHANGED], 0, priv->dot, TRUE);
+ }
+ return;
+}
+
+void
+message_service_dbus_set_icon (MessageServiceDbus * self, gboolean hidden)
+{
+ MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self);
+ /* Do signal */
+ if (hidden != priv->hidden) {
+ priv->hidden = hidden;
+ g_signal_emit(G_OBJECT(self), signals[ICON_CHANGED], 0, priv->hidden, TRUE);
+ }
+ return;
+}
diff --git a/src/messages-service-dbus.h b/src/messages-service-dbus.h
new file mode 100644
index 0000000..7a8574e
--- /dev/null
+++ b/src/messages-service-dbus.h
@@ -0,0 +1,62 @@
+/*
+An indicator to show information that is in messaging applications
+that the user is using.
+
+Copyright 2009 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MESSAGE_SERVICE_DBUS_H__
+#define __MESSAGE_SERVICE_DBUS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MESSAGE_SERVICE_DBUS_TYPE (message_service_dbus_get_type ())
+#define MESSAGE_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbus))
+#define MESSAGE_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusClass))
+#define IS_MESSAGE_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MESSAGE_SERVICE_DBUS_TYPE))
+#define IS_MESSAGE_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MESSAGE_SERVICE_DBUS_TYPE))
+#define MESSAGE_SERVICE_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusClass))
+
+#define MESSAGE_SERVICE_DBUS_SIGNAL_ATTENTION_CHANGED "attention-changed"
+#define MESSAGE_SERVICE_DBUS_SIGNAL_ICON_CHANGED "icon-changed"
+
+typedef struct _MessageServiceDbus MessageServiceDbus;
+typedef struct _MessageServiceDbusClass MessageServiceDbusClass;
+
+struct _MessageServiceDbusClass {
+ GObjectClass parent_class;
+
+ void (*attention_changed) (gboolean dot);
+ void (*icon_changed) (gboolean hidden);
+};
+
+struct _MessageServiceDbus {
+ GObject parent;
+};
+
+GType message_service_dbus_get_type (void);
+MessageServiceDbus * message_service_dbus_new (void);
+void message_service_dbus_set_attention (MessageServiceDbus * self, gboolean attention);
+void message_service_dbus_set_icon (MessageServiceDbus * self, gboolean hidden);
+
+G_END_DECLS
+
+#endif
diff --git a/src/messages-service.c b/src/messages-service.c
index 384198a..093ebfd 100644
--- a/src/messages-service.c
+++ b/src/messages-service.c
@@ -33,6 +33,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "launcher-menu-item.h"
#include "dbus-data.h"
#include "dirs.h"
+#include "messages-service-dbus.h"
static IndicateListener * listener;
static GList * serverList = NULL;
@@ -41,6 +42,8 @@ static GList * launcherList = NULL;
static DbusmenuMenuitem * root_menuitem = NULL;
static GMainLoop * mainloop = NULL;
+static MessageServiceDbus * dbus_interface = NULL;
+
static void server_count_changed (AppMenuItem * appitem, guint count, gpointer data);
static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data);
@@ -57,6 +60,7 @@ static gboolean blacklist_remove (gpointer data);
static void blacklist_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data);
static void app_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data);
static gboolean destroy_launcher (gpointer data);
+static void check_hidden (void);
/*
@@ -164,6 +168,29 @@ launcherList_sort (gconstpointer a, gconstpointer b)
return g_strcmp0(pan, pbn);
}
+static void
+launcherList_count_helper (gpointer data, gpointer user_data)
+{
+ guint * count = (guint *)user_data;
+ launcherList_t * li = (launcherList_t *)data;
+
+ if (!launcher_menu_item_get_eclipsed(li->menuitem)) {
+ *count = *count + 1;
+ }
+
+ return;
+}
+
+static guint
+launcherList_count (void)
+{
+ guint count = 0;
+
+ g_list_foreach(launcherList, launcherList_count_helper, &count);
+
+ return count;
+}
+
/*
* Black List
*/
@@ -195,7 +222,7 @@ blacklist_init (gpointer data)
GError * error = NULL;
GDir * dir = g_dir_open(blacklistdir, 0, &error);
if (dir == NULL) {
- g_warning("Unable to open blacklist directory (%s): %s", blacklistdir, error->message);
+ g_warning("Unable to open blacklist directory (%s): %s", blacklistdir, error == NULL ? "No Message" : error->message);
g_error_free(error);
g_free(blacklistdir);
return FALSE;
@@ -260,6 +287,8 @@ blacklist_add (gpointer udata)
}
}
+ check_hidden();
+
return FALSE;
}
@@ -309,6 +338,8 @@ blacklist_remove (gpointer data)
g_warning("Unable to remove '%s' with value '%s'", definition_file, (gchar *)key);
}
+ check_hidden();
+
return FALSE;
}
@@ -406,6 +437,7 @@ server_added (IndicateListener * listener, IndicateListenerServer * server, gcha
/* Should be prepend ^ */
resort_menu(menushell);
+ check_hidden();
return;
}
@@ -438,7 +470,7 @@ server_count_changed (AppMenuItem * appitem, guint count, gpointer data)
if (count != 0) {
g_debug("Setting image to 'new'");
showing_new_icon = TRUE;
- /* gtk_image_set_from_icon_name(GTK_IMAGE(main_image), "indicator-messages-new", DESIGN_TEAM_SIZE); */
+ message_service_dbus_set_attention(dbus_interface, TRUE);
return;
}
@@ -459,7 +491,7 @@ server_count_changed (AppMenuItem * appitem, guint count, gpointer data)
if (!we_have_indicators) {
g_debug("Setting image to boring");
showing_new_icon = FALSE;
- /* gtk_image_set_from_icon_name(GTK_IMAGE(main_image), "indicator-messages", DESIGN_TEAM_SIZE); */
+ message_service_dbus_set_attention(dbus_interface, FALSE);
}
return;
@@ -508,6 +540,7 @@ server_removed (IndicateListener * listener, IndicateListenerServer * server, gc
/* Simulate a server saying zero to recalculate icon */
server_count_changed(NULL, 0, NULL);
+ check_hidden();
return;
}
@@ -540,6 +573,24 @@ menushell_foreach_cb (DbusmenuMenuitem * data_mi, gpointer data_ms) {
}
static void
+check_hidden (void)
+{
+ g_debug("Checking Hidden...");
+ gboolean hide = FALSE;
+ if (launcherList_count() == 0) {
+ g_debug("\tZero Launchers");
+ /* If we don't have visible launchers we need to look more */
+ if (g_list_length(serverList) == 0) {
+ g_debug("\tZero Applications");
+ hide = TRUE;
+ }
+ }
+
+ message_service_dbus_set_icon(dbus_interface, hide);
+ return;
+}
+
+static void
resort_menu (DbusmenuMenuitem * menushell)
{
guint position = 0;
@@ -857,7 +908,7 @@ destroy_launcher (gpointer data)
g_list_free(li->appdiritems);
if (li->menuitem != NULL) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li->menuitem), "visible", "false");
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
dbusmenu_menuitem_child_delete(root_menuitem, DBUSMENU_MENUITEM(li->menuitem));
g_object_unref(G_OBJECT(li->menuitem));
li->menuitem = NULL;
@@ -986,6 +1037,8 @@ main (int argc, char ** argv)
return 1;
}
+ dbus_interface = message_service_dbus_new();
+
listener = indicate_listener_ref_default();
serverList = NULL;
diff --git a/src/messages-service.xml b/src/messages-service.xml
new file mode 100644
index 0000000..f991179
--- /dev/null
+++ b/src/messages-service.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.ayatana.indicator.messages.service">
+
+<!-- Methods -->
+ <method name="Watch">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true" />
+ </method>
+ <method name="AttentionRequested">
+ <arg type="b" name="dot" direction="out" />
+ </method>
+ <method name="IconShown">
+ <arg type="b" name="hidden" direction="out" />
+ </method>
+
+<!-- Signals -->
+ <signal name="AttentionChanged">
+ <arg type="b" name="dot" direction="out" />
+ </signal>
+ <signal name="IconChanged">
+ <arg type="b" name="hidden" direction="out" />
+ </signal>
+
+ </interface>
+</node>