aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indicator-messages.c')
-rw-r--r--src/indicator-messages.c455
1 files changed, 4 insertions, 451 deletions
diff --git a/src/indicator-messages.c b/src/indicator-messages.c
index b0aaffd..a8db436 100644
--- a/src/indicator-messages.c
+++ b/src/indicator-messages.c
@@ -22,455 +22,17 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include <gtk/gtk.h>
-#include <libindicate/listener.h>
+#include <libdbusmenu-gtk/menu.h>
#include <libindicator/indicator.h>
INDICATOR_SET_VERSION
INDICATOR_SET_NAME("messages")
-#include "im-menu-item.h"
-#include "app-menu-item.h"
-
-static IndicateListener * listener;
-static GList * serverList;
static GtkWidget * main_image;
-static void server_count_changed (AppMenuItem * appitem, guint count, gpointer data);
-static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data);
-static void im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data);
-static void reconsile_list_and_menu (GList * serverlist, GtkMenuShell * menushell);
-static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
-
#define DESIGN_TEAM_SIZE design_team_size
static GtkIconSize design_team_size;
-typedef struct _serverList_t serverList_t;
-struct _serverList_t {
- IndicateListenerServer * server;
- AppMenuItem * menuitem;
- GList * imList;
-};
-
-static gint
-serverList_equal (gconstpointer a, gconstpointer b)
-{
- serverList_t * pa, * pb;
-
- pa = (serverList_t *)a;
- pb = (serverList_t *)b;
-
- const gchar * pas = INDICATE_LISTENER_SERVER_DBUS_NAME(pa->server);
- const gchar * pbs = INDICATE_LISTENER_SERVER_DBUS_NAME(pb->server);
-
- return g_strcmp0(pas, pbs);
-}
-
-static gint
-serverList_sort (gconstpointer a, gconstpointer b)
-{
- serverList_t * pa, * pb;
-
- pa = (serverList_t *)a;
- pb = (serverList_t *)b;
-
- const gchar * pan = app_menu_item_get_name(pa->menuitem);
- const gchar * pbn = app_menu_item_get_name(pb->menuitem);
-
- return g_strcmp0(pan, pbn);
-}
-
-typedef struct _imList_t imList_t;
-struct _imList_t {
- IndicateListenerServer * server;
- IndicateListenerIndicator * indicator;
- GtkWidget * menuitem;
- gulong timechange_cb;
-};
-
-static gboolean
-imList_equal (gconstpointer a, gconstpointer b)
-{
- imList_t * pa, * pb;
-
- pa = (imList_t *)a;
- pb = (imList_t *)b;
-
- const gchar * pas = INDICATE_LISTENER_SERVER_DBUS_NAME(pa->server);
- const gchar * pbs = INDICATE_LISTENER_SERVER_DBUS_NAME(pb->server);
-
- guint pai = INDICATE_LISTENER_INDICATOR_ID(pa->indicator);
- guint pbi = INDICATE_LISTENER_INDICATOR_ID(pb->indicator);
-
- g_debug("\tComparing (%s %d) to (%s %d)", pas, pai, pbs, pbi);
-
- return !((!g_strcmp0(pas, pbs)) && (pai == pbi));
-}
-
-static gint
-imList_sort (gconstpointer a, gconstpointer b)
-{
- imList_t * pa, * pb;
-
- pa = (imList_t *)a;
- pb = (imList_t *)b;
-
- return (gint)(im_menu_item_get_seconds(IM_MENU_ITEM(pb->menuitem)) - im_menu_item_get_seconds(IM_MENU_ITEM(pa->menuitem)));
-}
-
-static void
-server_added (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
-{
- g_debug("Server Added '%s' of type '%s'.", INDICATE_LISTENER_SERVER_DBUS_NAME(server), type);
- if (type == NULL) {
- return;
- }
-
- if (type[0] == '\0') {
- return;
- }
-
- if (strncmp(type, "message", strlen("message"))) {
- g_debug("\tServer type '%s' is not a message based type.", type);
- return;
- }
-
- GtkMenuShell * menushell = GTK_MENU_SHELL(data);
- if (menushell == NULL) {
- g_error("\tData in callback is not a menushell");
- return;
- }
-
- AppMenuItem * menuitem = app_menu_item_new(listener, server);
- g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), NULL);
- g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell);
-
- serverList_t * sl_item = g_new0(serverList_t, 1);
- sl_item->server = server;
- sl_item->menuitem = menuitem;
- sl_item->imList = NULL;
-
- /* Incase we got an indicator first */
- GList * alreadythere = g_list_find_custom(serverList, sl_item, serverList_equal);
- if (alreadythere != NULL) {
- g_free(sl_item);
- sl_item = (serverList_t *)alreadythere->data;
- sl_item->menuitem = menuitem;
- serverList = g_list_sort(serverList, serverList_sort);
- } else {
- serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
- }
-
- gtk_menu_shell_prepend(menushell, GTK_WIDGET(menuitem));
- gtk_widget_show(GTK_WIDGET(menuitem));
- gtk_widget_show(GTK_WIDGET(main_image));
-
- reconsile_list_and_menu(serverList, menushell);
-
- return;
-}
-
-static void
-server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data)
-{
- serverList = g_list_sort(serverList, serverList_sort);
- reconsile_list_and_menu(serverList, GTK_MENU_SHELL(data));
- return;
-}
-
-static void
-server_count_changed (AppMenuItem * appitem, guint count, gpointer data)
-{
- static gboolean showing_new_icon = FALSE;
-
- /* Quick check for a common case */
- if (count != 0 && showing_new_icon) {
- return;
- }
-
- /* Odd that we'd get a signal in this case, but let's
- take it out of the mix too */
- if (count == 0 && !showing_new_icon) {
- return;
- }
-
- 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);
- return;
- }
-
- /* Okay, now at this point the count is zero and it
- might result in a switching of the icon back to being
- the plain one. Let's check. */
-
- gboolean we_have_indicators = FALSE;
- GList * appitems = serverList;
- for (; appitems != NULL; appitems = appitems->next) {
- AppMenuItem * appitem = ((serverList_t *)appitems->data)->menuitem;
- if (app_menu_item_get_count(appitem) != 0) {
- we_have_indicators = TRUE;
- break;
- }
- }
-
- 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);
- }
-
- return;
-}
-
-static void
-im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data)
-{
- serverList_t * sl = (serverList_t *)data;
- sl->imList = g_list_sort(sl->imList, imList_sort);
- reconsile_list_and_menu(serverList, GTK_MENU_SHELL(gtk_widget_get_parent(GTK_WIDGET(imitem))));
- return;
-}
-
-static void
-server_removed (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
-{
- g_debug("Removing server: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server));
- serverList_t slt;
- slt.server = server;
- GList * lookup = g_list_find_custom(serverList, &slt, serverList_equal);
-
- if (lookup == NULL) {
- g_debug("\tUnable to find server: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server));
- return;
- }
-
- serverList_t * sltp = (serverList_t *)lookup->data;
-
- while (sltp->imList) {
- imList_t * imitem = (imList_t *)sltp->imList->data;
- indicator_removed(listener, server, imitem->indicator, "message", data);
- }
-
- serverList = g_list_remove(serverList, sltp);
-
- if (sltp->menuitem != NULL) {
- gtk_widget_hide(GTK_WIDGET(sltp->menuitem));
- gtk_container_remove(GTK_CONTAINER(data), GTK_WIDGET(sltp->menuitem));
- }
-
- g_free(sltp);
-
- if (g_list_length(serverList) == 0) {
- gtk_widget_hide(main_image);
- } else {
- /* Simulate a server saying zero to recalculate icon */
- server_count_changed(NULL, 0, NULL);
- }
-
- return;
-}
-
-typedef struct _menushell_location menushell_location_t;
-struct _menushell_location {
- const IndicateListenerServer * server;
- gint position;
- gboolean found;
-};
-
-static void
-menushell_foreach_cb (GtkWidget * data_mi, gpointer data_ms) {
- menushell_location_t * msl = (menushell_location_t *)data_ms;
-
- if (msl->found) return;
-
- msl->position++;
-
- if (!IS_APP_MENU_ITEM(data_mi)) {
- return;
- }
-
- AppMenuItem * appmenu = APP_MENU_ITEM(data_mi);
- if (!g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME((IndicateListenerServer*)msl->server), INDICATE_LISTENER_SERVER_DBUS_NAME(app_menu_item_get_server(appmenu)))) {
- msl->found = TRUE;
- }
-
- return;
-}
-
-static void
-reconsile_list_and_menu (GList * serverlist, GtkMenuShell * menushell)
-{
- guint position = 0;
- GList * serverentry;
-
- g_debug("Reordering Menu:");
-
- for (serverentry = serverList; serverentry != NULL; serverentry = serverentry->next) {
- serverList_t * si = (serverList_t *)serverentry->data;
- if (si->menuitem != NULL) {
- g_debug("\tMoving app %s to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(si->server), position);
- gtk_menu_reorder_child(GTK_MENU(menushell), GTK_WIDGET(si->menuitem), position);
- position++;
- }
-
- GList * imentry;
- for (imentry = si->imList; imentry != NULL; imentry = imentry->next) {
- imList_t * imi = (imList_t *)imentry->data;
-
- if (imi->menuitem != NULL) {
- g_debug("\tMoving indicator on %s id %d to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(imi->server), INDICATE_LISTENER_INDICATOR_ID(imi->indicator), position);
- gtk_menu_reorder_child(GTK_MENU(menushell), imi->menuitem, position);
- position++;
- }
- }
- }
-
- return;
-}
-
-static void
-subtype_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
-{
- GtkMenuShell * menushell = GTK_MENU_SHELL(data);
- if (menushell == NULL) {
- g_error("Data in callback is not a menushell");
- return;
- }
-
- if (property == NULL || g_strcmp0(property, "subtype")) {
- /* We should only ever get subtypes, but just in case */
- g_warning("Subtype callback got a property '%s'", property);
- return;
- }
-
- if (propertydata == NULL || propertydata[0] == '\0') {
- /* It's possible that this message didn't have a subtype. That's
- * okay, but we don't want to display those */
- g_debug("No subtype");
- return;
- }
-
- g_debug("Message subtype: %s", propertydata);
-
- if (!g_strcmp0(propertydata, "im") || !g_strcmp0(propertydata, "login")) {
- imList_t * listItem = g_new0(imList_t, 1);
- listItem->server = server;
- listItem->indicator = indicator;
-
- g_debug("Building IM Item");
- ImMenuItem * menuitem = im_menu_item_new(listener, server, indicator, !g_strcmp0(propertydata, "im"));
- g_object_ref(G_OBJECT(menuitem));
- listItem->menuitem = GTK_WIDGET(menuitem);
-
- g_debug("Finding the server entry");
- serverList_t sl_item_local;
- serverList_t * sl_item = NULL;
- sl_item_local.server = server;
- GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal);
-
- if (serverentry == NULL) {
- /* This sucks, we got an indicator before the server. I guess
- that's the joy of being asynchronous */
- serverList_t * sl_item = g_new0(serverList_t, 1);
- sl_item->server = server;
- sl_item->menuitem = NULL;
- sl_item->imList = NULL;
-
- serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
- } else {
- sl_item = (serverList_t *)serverentry->data;
- }
-
- g_debug("Adding to IM List");
- sl_item->imList = g_list_insert_sorted(sl_item->imList, listItem, imList_sort);
- listItem->timechange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_TIME_CHANGED, G_CALLBACK(im_time_changed), sl_item);
-
- g_debug("Placing in Shell");
- menushell_location_t msl;
- msl.found = FALSE;
- msl.position = 0;
- msl.server = server;
-
- gtk_container_foreach(GTK_CONTAINER(menushell), menushell_foreach_cb, &msl);
- if (msl.found) {
- gtk_menu_shell_insert(menushell, GTK_WIDGET(menuitem), msl.position);
- } else {
- g_warning("Unable to find server menu item");
- gtk_menu_shell_append(menushell, GTK_WIDGET(menuitem));
- }
- }
-
- return;
-}
-
-static void
-indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
-{
- if (type == NULL || g_strcmp0(type, "message")) {
- /* We only care about message type indicators
- all of the others can go to the bit bucket */
- g_debug("Ignoreing indicator of type '%s'", type);
- return;
- }
- g_debug("Got a message");
-
- indicate_listener_get_property(listener, server, indicator, "subtype", subtype_cb, data);
- return;
-}
-
-static void
-indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
-{
- g_debug("Removing %s %d", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator));
- if (type == NULL || g_strcmp0(type, "message")) {
- /* We only care about message type indicators
- all of the others can go to the bit bucket */
- g_debug("Ignoreing indicator of type '%s'", type);
- return;
- }
-
- gboolean removed = FALSE;
-
- serverList_t sl_item_local;
- serverList_t * sl_item = NULL;
- sl_item_local.server = server;
- GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal);
- if (serverentry == NULL) {
- return;
- }
- sl_item = (serverList_t *)serverentry->data;
-
- /* Look in the IM Hash Table */
- imList_t listData;
- listData.server = server;
- listData.indicator = indicator;
-
- GList * listItem = g_list_find_custom(sl_item->imList, &listData, imList_equal);
- GtkWidget * menuitem = NULL;
- imList_t * ilt = NULL;
- if (listItem != NULL) {
- ilt = (imList_t *)listItem->data;
- menuitem = ilt->menuitem;
- }
-
- if (!removed && menuitem != NULL) {
- sl_item->imList = g_list_remove(sl_item->imList, ilt);
- g_signal_handler_disconnect(menuitem, ilt->timechange_cb);
- g_free(ilt);
-
- gtk_widget_hide(menuitem);
- gtk_container_remove(GTK_CONTAINER(data), menuitem);
- removed = TRUE;
- }
-
- if (!removed) {
- g_warning("We were asked to remove %s %d but we didn't.", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator));
- }
-
- return;
-}
-
GtkLabel *
get_label (void)
{
@@ -485,23 +47,14 @@ 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);
}
GtkMenu *
get_menu (void)
{
- listener = indicate_listener_ref_default();
- serverList = NULL;
-
- GtkWidget * submenu = gtk_menu_new();
- gtk_widget_show(submenu);
-
- g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added), submenu);
- g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_CALLBACK(indicator_removed), submenu);
- g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_ADDED, G_CALLBACK(server_added), submenu);
- g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_REMOVED, G_CALLBACK(server_removed), submenu);
-
- return GTK_MENU(submenu);
+ return GTK_MENU(dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT));
}