ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #00076
[Merge] lp:~ted/indicator-messages/newapi.ubuntu into lp:indicator-messages
David Barth has proposed merging lp:~ted/indicator-messages/newapi.ubuntu into lp:indicator-messages.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
Assuming the branch is in a merge'able state.
It provides:
6. Supporting new libindicate that no longer supports message types (Email, IM, etc...)
7. libindicate code is done, needs to be code reviewed
as stated in https://bugs.edge.launchpad.net/indicator-messages/+bug/423013/comments/2
Aurélien: can you have a look at this branch too please?
--
https://code.launchpad.net/~ted/indicator-messages/newapi.ubuntu/+merge/11317
Your team ayatana-commits is subscribed to branch lp:indicator-messages.
=== added directory '.bzr-builddeb'
=== added file '.bzr-builddeb/default.conf'
--- .bzr-builddeb/default.conf 1970-01-01 00:00:00 +0000
+++ .bzr-builddeb/default.conf 2009-03-19 11:22:21 +0000
@@ -0,0 +1,2 @@
+[BUILDDEB]
+merge = True
=== modified file 'configure.ac'
--- configure.ac 2009-09-03 19:06:22 +0000
+++ configure.ac 2009-09-04 20:37:59 +0000
@@ -34,7 +34,6 @@
gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION
indicator >= $INDICATOR_REQUIRED_VERSION
indicate >= $INDICATE_REQUIRED_VERSION
- indicate-gtk >= $INDICATE_REQUIRED_VERSION
dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION)
AC_SUBST(APPLET_CFLAGS)
AC_SUBST(APPLET_LIBS)
=== added directory 'debian'
=== added file 'debian/changelog'
--- debian/changelog 1970-01-01 00:00:00 +0000
+++ debian/changelog 2009-09-05 16:44:38 +0000
@@ -0,0 +1,178 @@
+indicator-messages (0.2.0-0ubuntu3~ppa2~newapi2) karmic; urgency=low
+
+ * Fix for the changes in libindicate (fixes)
+
+ -- Ted Gould <ted@xxxxxxxxxx> Sat, 05 Sep 2009 11:44:34 -0500
+
+indicator-messages (0.2.0-0ubuntu3~ppa2~newapi1) karmic; urgency=low
+
+ * Merging in changes for the new libindicate API
+
+ -- Ted Gould <ted@xxxxxxxxxx> Sat, 05 Sep 2009 11:13:51 -0500
+
+indicator-messages (0.2.0-0ubuntu3~ppa1) karmic; urgency=low
+
+ * Bumping version after ~ubuntu-desktop merge.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Fri, 04 Sep 2009 13:56:06 -0500
+
+indicator-messages (0.2.0-0ubuntu1~ppa3) karmic; urgency=low
+
+ * Upstream usage of new Dbusmenu 0.1.1 defines.
+ * debian/control: Increasing Dbusmenu dependencies.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Fri, 04 Sep 2009 13:50:50 -0500
+
+indicator-messages (0.2.0-0ubuntu1~ppa2) karmic; urgency=low
+
+ * Upstream update to dbusmenu dependency.
+ * debian/control: Adding dependency information for libdbusmenu
+ to say >= 0.1.0 to match upstream build system.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Thu, 27 Aug 2009 14:01:03 -0500
+
+indicator-messages (0.2.0-0ubuntu2) karmic; urgency=low
+
+ * debian/control
+ - Bump build depends on dbusmenu to 0.1.0
+
+ -- Ken VanDine <ken.vandine@xxxxxxxxxxxxx> Thu, 27 Aug 2009 21:14:46 +0200
+
+indicator-messages (0.2.0-0ubuntu1) karmic; urgency=low
+
+ [ Ted Gould ]
+ * Upstream version 0.2.0
+ * debian/control: Adding dependency information for libdbusmenu
+ to say >= 0.0.2 to match upstream build system.
+ * debian/watch: Changing to use indicator-messages project.
+
+ [ Martin Pitt ]
+ * debian/control: Update Vcs-Bzr: for new branch location.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Thu, 27 Aug 2009 20:46:27 +0200
+
+indicator-messages (0.2.0~bzr124-0ubuntu1) karmic; urgency=low
+
+ * Update to fix build issue
+
+ -- Sebastien Bacher <seb128@xxxxxxxxxx> Fri, 07 Aug 2009 17:12:40 +0100
+
+indicator-messages (0.2.0~bzr121-0ubuntu3) karmic; urgency=low
+
+ * Fix to dereference the application menu items correctly so that
+ the signal handlers are dropped as well. (lp: #410251)
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 05 Aug 2009 19:00:31 +0100
+
+indicator-messages (0.2.0~bzr121-0ubuntu2) karmic; urgency=low
+
+ * Run autogen.sh before upload
+
+ -- Jonathan Riddell <jriddell@xxxxxxxxxx> Wed, 05 Aug 2009 00:42:39 +0100
+
+indicator-messages (0.2.0~bzr121-0ubuntu1) karmic; urgency=low
+
+ [ Ted Gould ]
+ * debian/control: Adding in a build dep on libindicate-gtk-dev
+ * Changes for the changing libindicate stuff.
+ * Merge in the dbusmenu changes from the dbusmenu branch
+ * debian/control: Adding in a build dependency on libdbusmenu-glib and
+ libdbusmenu-gtk to catch up with the merge.
+
+ -- Jonathan Riddell <jriddell@xxxxxxxxxx> Wed, 05 Aug 2009 00:21:50 +0100
+
+indicator-messages (0.2.0~bzr120-0ubuntu1) jaunty; urgency=low
+
+ * Fix to track the timer. (LP: #365187)
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 13 May 2009 09:56:20 -0500
+
+indicator-messages (0.2.0~bzr119-0ubuntu1) jaunty; urgency=low
+
+ * Upstream update
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 22 Apr 2009 23:34:21 -0500
+
+indicator-messages (0.2.0~bzr116-0ubuntu3) jaunty; urgency=low
+
+ * debian/rules: Adding a rule to remove the .la/.a clutter
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 22 Apr 2009 16:46:59 -0500
+
+indicator-messages (0.2.0~bzr116-0ubuntu2) jaunty; urgency=low
+
+ * debian/control: libindicator-dev to ~bzr301
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 22 Apr 2009 15:58:45 -0500
+
+indicator-messages (0.2.0~bzr116-0ubuntu1) jaunty; urgency=low
+
+ * Upstream release
+ * Bug fixes
+ * Update API to new libindicator
+ * debian/control: Adding new dependency on libindicator-dev
+
+ -- Ted Gould <ted@xxxxxxxxxx> Wed, 22 Apr 2009 15:45:21 -0500
+
+indicator-messages (0.1.6-0ubuntu1) jaunty; urgency=low
+
+ * New upstream version
+ * Patch from Cody Russell to fix LP: #359018 by correctly implementing
+ the finalize functions.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Tue, 14 Apr 2009 11:32:00 +0200
+
+indicator-messages (0.1.5-0ubuntu1) jaunty; urgency=low
+
+ * New upstream version
+ * Fixes the lifecycle of the various structures tracking the messages
+ and applications. Fixing bugs like (LP: #355616) (LP: #352881)
+ * Fixes the visual appearance by setting the widget name to grab the
+ style settings from the main applet. (LP: #351979)
+ * debian/control: Upgrading dependency on libindicate-dev to 0.1.5 or
+ higher as the new version requires that.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Fri, 03 Apr 2009 16:32:49 -0500
+
+indicator-messages (0.1.4-0ubuntu1) jaunty; urgency=low
+
+ * New upstream version
+ * Adding the display of indicators that are login messages coming from
+ other applications. (LP: #345494)
+ * Making all times displayed for IM messages relative instead of
+ absolute. (LP: #346345)
+ * Cleaning up the server removal code. May fix (LP: #345599), I can't
+ recreate it anymore afterwards.
+
+ -- Ted Gould <ted@xxxxxxxxxx> Mon, 30 Mar 2009 09:40:40 +0200
+
+indicator-messages (0.1.3-0ubuntu1) jaunty; urgency=low
+
+ [ Ted Gould ]
+ * New upstream version.
+ - Now changes the icon based on non-IM indicators so that Evolution
+ works much better. (LP: #342480)
+ - Now the menu items are in a predictable order, alphabetical.
+ - The Messages for a particular client (i.e. Pidgin) are grouped with
+ the client they're associated with.
+ - Adjusting the icon size to match the new one in the Human theme.
+ - Adjusting the build so that all the different libraries are not
+ built in a versioned manner. Now it's just one .so, which is
+ what it should have been originally.
+
+ [ Martin Pitt ]
+ * Add debian/watch.
+ * Add bzr-builddeb configuration.
+ * debian/copyright: Fix download location.
+
+ -- Martin Pitt <martin.pitt@xxxxxxxxxx> Thu, 19 Mar 2009 12:23:17 +0100
+
+indicator-messages (0.1-0ubuntu1) jaunty; urgency=low
+
+ * Initial release, based on DX team's PPA packaging branch.
+ (lp:~indicator-applet-developers/indicator-applet/messages-packaging)
+ * debian/control: Add Homepage:, Vcs-Bzr:, and fix package
+ description.
+ * debian/copyright: Properly describe license.
+
+ -- Martin Pitt <martin.pitt@xxxxxxxxxx> Tue, 17 Feb 2009 11:35:38 +0100
=== added file 'debian/control'
--- debian/control 1970-01-01 00:00:00 +0000
+++ debian/control 2009-09-04 18:54:25 +0000
@@ -0,0 +1,29 @@
+Source: indicator-messages
+Section: gnome
+Priority: optional
+Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@xxxxxxxxxxxxxxxx>
+Build-Depends: debhelper (>= 5.0),
+ cdbs (>= 0.4.41),
+ libgtk2.0-dev (>= 2.12.0),
+ libdbus-glib-1-dev,
+ gnome-doc-utils,
+ scrollkeeper,
+ intltool,
+ libindicate-dev (>= 0.2.0~bzr298),
+ libindicate-gtk-dev (>= 0.2.0~bzr298),
+ libindicator-dev (>= 0.2.0~bzr301),
+ libdbusmenu-gtk-dev (>= 0.1.1),
+ libdbusmenu-glib-dev (>= 0.1.1)
+Standards-Version: 3.8.0
+Homepage: https://launchpad.net/indicator-applet
+Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/indicator-messages/ubuntu
+
+Package: indicator-messages
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, indicator-applet
+Description: GNOME panel indicator applet for messages
+ indicator-applet is an applet to display information from
+ various applications consistently in the GNOME panel.
+ .
+ This package provides support for messaging applications.
+
=== added file 'debian/copyright'
--- debian/copyright 1970-01-01 00:00:00 +0000
+++ debian/copyright 2009-03-19 11:22:57 +0000
@@ -0,0 +1,33 @@
+This package was debianized by Ted Gould <ted@xxxxxxxxxxxxx> on
+Wed, 11 Feb 2009 15:41:06 -0600.
+
+It was downloaded from <http://launchpad.net/indicator-applet/>
+
+Upstream Author:
+
+ Ted Gould <ted@xxxxxxxxxxxxx>
+
+Copyright:
+
+ Copyright (C) 2009 Canonical Ltd.
+
+License:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, version 3 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY 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, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL-3'.
+
+The Debian packaging is (C) 2009, Canonical Ltd. and
+is licensed under the GPLv3, see `/usr/share/common-licenses/GPL-3'.
=== added file 'debian/rules'
--- debian/rules 1970-01-01 00:00:00 +0000
+++ debian/rules 2009-04-22 21:46:57 +0000
@@ -0,0 +1,12 @@
+#!/usr/bin/make -f
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/gnome.mk
+
+DEB_CONFIGURE_EXTRA_FLAGS += --disable-scrollkeeper
+LDFLAGS += -Wl,-z,defs -Wl,--as-needed
+
+binary-install/indicator-messages::
+ # remove .a/.la clutter
+ rm -f debian/$(cdbs_curpkg)/usr/lib/indicators/*/*.a
+ rm -f debian/$(cdbs_curpkg)/usr/lib/indicators/*/*.la
=== added file 'debian/watch'
--- debian/watch 1970-01-01 00:00:00 +0000
+++ debian/watch 2009-08-27 18:10:28 +0000
@@ -0,0 +1,2 @@
+version=3
+http://launchpad.net/indicator-messages/+download .*/indicator-messages-([0-9.]+)\.tar\.gz
=== modified file 'src/app-menu-item.c'
--- src/app-menu-item.c 2009-08-26 21:47:55 +0000
+++ src/app-menu-item.c 2009-09-05 16:43:36 +0000
@@ -27,6 +27,7 @@
#include <glib/gi18n.h>
#include <gio/gdesktopappinfo.h>
#include "app-menu-item.h"
+#include "dbus-data.h"
enum {
COUNT_CHANGED,
@@ -47,7 +48,6 @@
GAppInfo * appinfo;
gchar * desktop;
guint unreadcount;
- gboolean count_on_label;
};
#define APP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_MENU_ITEM_TYPE, AppMenuItemPrivate))
@@ -58,14 +58,12 @@
static void app_menu_item_dispose (GObject *object);
static void app_menu_item_finalize (GObject *object);
static void activate_cb (AppMenuItem * self, gpointer data);
-static void type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data);
+static void count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data);
+static void count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data);
static void desktop_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data);
-static void indicator_added_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
-static void indicator_removed_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
static void update_label (AppMenuItem * self);
-
-
+/* GObject Boilerplate */
G_DEFINE_TYPE (AppMenuItem, app_menu_item, DBUSMENU_TYPE_MENUITEM);
static void
@@ -108,8 +106,6 @@
priv->appinfo = NULL;
priv->desktop = NULL;
priv->unreadcount = 0;
- priv->count_on_label = FALSE;
-
return;
}
@@ -120,9 +116,6 @@
AppMenuItem * self = APP_MENU_ITEM(object);
AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
- g_signal_handlers_disconnect_by_func(G_OBJECT(priv->listener), G_CALLBACK(indicator_added_cb), self);
- g_signal_handlers_disconnect_by_func(G_OBJECT(priv->listener), G_CALLBACK(indicator_removed_cb), self);
-
g_object_unref(priv->listener);
G_OBJECT_CLASS (app_menu_item_parent_class)->dispose (object);
@@ -158,63 +151,38 @@
AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
+ /* Copy the listener so we can use it later */
priv->listener = listener;
g_object_ref(G_OBJECT(listener));
+
+ /* Can not ref as not real GObject */
priv->server = server;
- /* Can not ref as not real GObject */
-
- g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added_cb), self);
- g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_CALLBACK(indicator_removed_cb), self);
-
- indicate_listener_server_get_type(listener, server, type_cb, self);
+
+ /* Set up listener signals */
+ g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_SERVER_COUNT_CHANGED, G_CALLBACK(count_changed), self);
+
+ /* Get the values we care about from the server */
indicate_listener_server_get_desktop(listener, server, desktop_cb, self);
+ indicate_listener_server_get_count(listener, server, count_cb, self);
g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL);
indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_DISPLAY);
indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_SIGNAL);
+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_COUNT);
+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_DISPLAY);
+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_SIGNAL);
+ indicate_listener_set_server_max_indicators(listener, server, MAX_NUMBER_OF_INDICATORS);
return self;
}
-static void
-type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data)
-{
- AppMenuItem * self = APP_MENU_ITEM(data);
- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
-
- if (priv->type != NULL) {
- g_free(priv->type);
- priv->type = NULL;
- }
-
- if (value == NULL) {
- g_warning("Type value is NULL, that shouldn't really happen");
- return;
- }
-
- priv->type = g_strdup(value);
-
- if (!(!g_strcmp0(priv->type, "message.instant") || !g_strcmp0(priv->type, "message.micro") || !g_strcmp0(priv->type, "message.im"))) {
- /* For IM and Microblogging we want the individual items, not a count */
- priv->count_on_label = TRUE;
- update_label(self);
-
- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_COUNT);
- } else {
- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_DISPLAY);
- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_SIGNAL);
- }
-
- return;
-}
-
static void
update_label (AppMenuItem * self)
{
AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
- if (priv->count_on_label && !priv->unreadcount < 1) {
+ if (priv->unreadcount > 0) {
/* 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);
@@ -227,6 +195,38 @@
return;
}
+/* Callback to the signal that the server count
+ has changed to a new value. This checks to see if
+ it's actually changed and if so signals everyone and
+ updates the label. */
+static void
+count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data)
+{
+ AppMenuItem * self = APP_MENU_ITEM(data);
+ AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
+
+ if (priv->unreadcount != count) {
+ priv->unreadcount = count;
+ update_label(self);
+ g_signal_emit(G_OBJECT(self), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
+ }
+
+ return;
+}
+
+/* Callback for getting the count property off
+ of the server. */
+static void
+count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data)
+{
+ count_changed(listener, server, value, data);
+ return;
+}
+
+/* Callback for when we ask the server for the path
+ to it's desktop file. We then turn it into an
+ app structure and start sucking data out of it.
+ Mostly the name. */
static void
desktop_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data)
{
@@ -268,46 +268,6 @@
return;
}
-static void
-indicator_added_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
-{
- g_return_if_fail(IS_APP_MENU_ITEM(data));
- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(data);
-
- if (g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_SERVER_DBUS_NAME(priv->server))) {
- /* Not us */
- return;
- }
-
- priv->unreadcount++;
-
- update_label(APP_MENU_ITEM(data));
- g_signal_emit(G_OBJECT(data), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
-
- return;
-}
-
-static void
-indicator_removed_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
-{
- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(data);
-
- if (g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_SERVER_DBUS_NAME(priv->server))) {
- /* Not us */
- return;
- }
-
- /* Should never happen, but let's have some protection on that */
- if (priv->unreadcount > 0) {
- priv->unreadcount--;
- }
-
- update_label(APP_MENU_ITEM(data));
- g_signal_emit(G_OBJECT(data), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
-
- return;
-}
-
guint
app_menu_item_get_count (AppMenuItem * appitem)
{
=== modified file 'src/dbus-data.h'
--- src/dbus-data.h 2009-08-27 01:06:09 +0000
+++ src/dbus-data.h 2009-09-04 22:14:23 +0000
@@ -12,4 +12,15 @@
#define LAUNCHER_MENUITEM_PROP_APP_NAME "application-name"
#define LAUNCHER_MENUITEM_PROP_APP_DESC "application-description"
+#define APPLICATION_MENUITEM_TYPE "application-item"
+#define APPLICATION_MENUITEM_PROP_NAME "app-name"
+#define APPLICATION_MENUITEM_PROP_COUNT "app-count"
+
+#define INDICATOR_MENUITEM_TYPE "indicator-item"
+#define INDICATOR_MENUITEM_PROP_LABEL "indicator-label"
+#define INDICATOR_MENUITEM_PROP_ICON "indicator-icon"
+#define INDICATOR_MENUITEM_PROP_RIGHT "right-side-text"
+
+#define MAX_NUMBER_OF_INDICATORS 7
+
#endif /* __DBUS_DATA_H__ */
=== modified file 'src/im-menu-item.c'
--- src/im-menu-item.c 2009-09-04 14:02:34 +0000
+++ src/im-menu-item.c 2009-09-04 22:31:29 +0000
@@ -25,12 +25,15 @@
#include <glib/gi18n.h>
#include <libdbusmenu-glib/client.h>
-#include <libindicate-gtk/indicator.h>
-#include <libindicate-gtk/listener.h>
+#include <libindicate/indicator.h>
+#include <libindicate/indicator-messages.h>
+#include <libindicate/listener.h>
#include "im-menu-item.h"
+#include "dbus-data.h"
enum {
TIME_CHANGED,
+ ATTENTION_CHANGED,
LAST_SIGNAL
};
@@ -45,8 +48,10 @@
IndicateListenerIndicator * indicator;
glong seconds;
- gboolean show_time;
+ gchar * count;
gulong indicator_changed;
+ gboolean attention;
+ gboolean show;
guint time_update_min;
};
@@ -81,7 +86,6 @@
static void indicator_modified_cb (IndicateListener * listener,
IndicateListenerServer * server,
IndicateListenerIndicator * indicator,
- gchar * type,
gchar * property,
ImMenuItem * self);
@@ -104,6 +108,13 @@
NULL, NULL,
g_cclosure_marshal_VOID__LONG,
G_TYPE_NONE, 1, G_TYPE_LONG);
+ signals[ATTENTION_CHANGED] = g_signal_new(IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ImMenuItemClass, attention_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
return;
}
@@ -147,20 +158,25 @@
G_OBJECT_CLASS (im_menu_item_parent_class)->finalize (object);
}
+/* Call back for getting icon data. It just passes it along
+ to the indicator so that it can visualize it. Not our problem. */
static void
icon_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
{
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM_PROP_ICON_DATA, propertydata);
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(data), INDICATOR_MENUITEM_PROP_ICON, propertydata);
return;
}
+/* This function takes the time and turns it into the appropriate
+ string to put on the right side of the menu item. Of course it
+ doesn't do that if there is a count set. If there's a count then
+ it gets that space. */
static void
update_time (ImMenuItem * self)
{
ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
- if (!priv->show_time) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "right-column", "");
+ if (priv->count != NULL) {
return;
}
@@ -191,13 +207,15 @@
}
if (timestring != NULL) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "right-column", "");
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, timestring);
g_free(timestring);
}
return;
}
+/* This is a wrapper around update_time that matches the prototype
+ needed to make this a timer callback. Silly. */
static gboolean
time_update_cb (gpointer data)
{
@@ -208,6 +226,10 @@
return TRUE;
}
+/* Yet another time function. This one takes the time as formated as
+ we get it from libindicate and turns it into the seconds that we're
+ looking for. It should only be called once at the init with a new
+ indicator and again when the value changes. */
static void
time_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, GTimeVal * propertydata, gpointer data)
{
@@ -238,26 +260,106 @@
return;
}
+/* Callback from libindicate that is for getting the sender information
+ on a particular indicator. */
static void
sender_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
{
g_debug("Got Sender Information");
ImMenuItem * self = IM_MENU_ITEM(data);
- if (self == NULL) {
- g_error("Menu Item callback called without a menu item");
- return;
- }
-
- if (property == NULL || g_strcmp0(property, "sender")) {
- g_warning("Sender callback called without being sent the sender. We got '%s' with value '%s'.", property, propertydata);
- return;
- }
-
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, propertydata);
-
- return;
-}
-
+
+ /* Our data should be right */
+ g_return_if_fail(self != NULL);
+ /* We should have a property name */
+ g_return_if_fail(property != NULL);
+ /* The Property should be sender or name */
+ g_return_if_fail(!g_strcmp0(property, "sender") || !g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME));
+
+ /* We might get the sender variable returning a
+ null string as it doesn't exist on newer clients
+ but we don't want to listen to that. */
+ if (!g_strcmp0(property, "sender") && property[0] == '\0') {
+ return;
+ }
+
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_LABEL, propertydata);
+
+ return;
+}
+
+/* Callback saying that the count is updated, we need to either put
+ that on the menu item or just remove it if the count is gone. If
+ that's the case we can update time. */
+static void
+count_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
+{
+ g_debug("Got Count Information");
+ ImMenuItem * self = IM_MENU_ITEM(data);
+
+ /* Our data should be right */
+ g_return_if_fail(self != NULL);
+ /* We should have a property name */
+ g_return_if_fail(property != NULL);
+ /* The Property should be count */
+ g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT));
+
+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
+
+ if (propertydata == NULL || propertydata[0] == '\0') {
+ /* The count is either being unset or it was never
+ set in the first place. */
+ if (priv->count != NULL) {
+ g_free(priv->count);
+ priv->count = NULL;
+ update_time(self);
+ }
+ return;
+ }
+
+ if (priv->count != NULL) {
+ g_free(priv->count);
+ }
+
+ priv->count = g_strdup_printf("(%s)", propertydata);
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, priv->count);
+
+ return;
+}
+
+/* This is getting the attention variable that's looking at whether
+ this indicator should be calling for attention or not. If we are,
+ we need to signal that. */
+static void
+attention_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
+{
+ g_debug("Got Attention Information");
+ ImMenuItem * self = IM_MENU_ITEM(data);
+
+ /* Our data should be right */
+ g_return_if_fail(self != NULL);
+ /* We should have a property name */
+ g_return_if_fail(property != NULL);
+ /* The Property should be count */
+ g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION));
+
+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
+
+ gboolean wantit;
+ if (propertydata == NULL || propertydata[0] == '\0' || !g_strcmp0(propertydata, "false")) {
+ wantit = FALSE;
+ } else {
+ wantit = TRUE;
+ }
+
+ if (priv->attention != wantit) {
+ priv->attention = wantit;
+ g_signal_emit(G_OBJECT(self), signals[ATTENTION_CHANGED], 0, wantit, TRUE);
+ }
+
+ return;
+}
+
+/* Callback when the item gets clicked on from the Messaging Menu */
static void
activate_cb (ImMenuItem * self, gpointer data)
{
@@ -266,8 +368,10 @@
indicate_listener_display(priv->listener, priv->server, priv->indicator);
}
+/* Callback when a property gets modified. It figures out which one
+ got modified and notifies the appropriate person. */
void
-indicator_modified_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gchar * property, ImMenuItem * self)
+indicator_modified_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, ImMenuItem * self)
{
ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
@@ -275,19 +379,29 @@
if (INDICATE_LISTENER_INDICATOR_ID(indicator) != INDICATE_LISTENER_INDICATOR_ID(priv->indicator)) return;
if (server != priv->server) return;
- if (!g_strcmp0(property, "sender")) {
+ /* Determine which property has been changed and request the
+ value go to the appropriate callback. */
+ if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME)) {
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self);
+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_TIME)) {
+ indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self);
+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ICON)) {
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self);
+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT)) {
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self);
+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION)) {
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self);
+ } else if (!g_strcmp0(property, "sender")) {
+ /* This is a compatibility string with v1 and should be removed */
+ g_debug("Indicator is using 'sender' property which is a v1 string.");
indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self);
- } else if (!g_strcmp0(property, "time")) {
- indicate_listener_get_property_time(listener, server, indicator, "time", time_cb, self);
- } else if (!g_strcmp0(property, "icon")) {
- indicate_listener_get_property(listener, server, indicator, "icon", icon_cb, self);
}
return;
}
ImMenuItem *
-im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gboolean show_time)
+im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator)
{
ImMenuItem * self = g_object_new(IM_MENU_ITEM_TYPE, NULL);
@@ -296,14 +410,21 @@
priv->listener = listener;
priv->server = server;
priv->indicator = indicator;
- priv->show_time = show_time;
+ priv->count = NULL;
priv->time_update_min = 0;
-
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "type", DBUSMENU_CLIENT_TYPES_IMAGE);
-
+ priv->attention = FALSE;
+ priv->show = TRUE;
+
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "type", INDICATOR_MENUITEM_TYPE);
+
+ indicate_listener_displayed(listener, server, indicator, TRUE);
+
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self);
+ indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self);
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self);
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self);
+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self);
indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self);
- indicate_listener_get_property_time(listener, server, indicator, "time", time_cb, self);
- indicate_listener_get_property(listener, server, indicator, "icon", icon_cb, self);
g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL);
priv->indicator_changed = g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED, G_CALLBACK(indicator_modified_cb), self);
@@ -311,9 +432,65 @@
return self;
}
+/* Gets the number of seconds for the creator
+ of this item. */
glong
im_menu_item_get_seconds (ImMenuItem * menuitem)
{
+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), 0);
+
ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
return priv->seconds;
}
+
+/* Gets whether or not this indicator item is
+ asking for attention or not. */
+gboolean
+im_menu_item_get_attention (ImMenuItem * menuitem)
+{
+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE);
+
+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
+ return priv->attention;
+}
+
+/* This takes care of items that need to be hidden, this is
+ usually because they go over the count of allowed indicators.
+ Which is more than a little bit silly. We shouldn't do that.
+ But we need to enforce it to save users against bad apps. */
+void
+im_menu_item_show (ImMenuItem * menuitem, gboolean show)
+{
+ g_return_if_fail(IS_IM_MENU_ITEM(menuitem));
+
+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
+
+ if (priv->show == show) {
+ return;
+ }
+
+ priv->show = show;
+ /* Tell the app what we're doing to it. If it's being
+ punished it needs to know about it. */
+ indicate_listener_displayed(priv->listener, priv->server, priv->indicator, priv->show);
+ if (priv->attention) {
+ /* If we were asking for attention we can ask for it
+ again if we're being shown, otherwise no. */
+ g_signal_emit(G_OBJECT(menuitem), signals[ATTENTION_CHANGED], 0, priv->show, TRUE);
+ }
+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, priv->show ? "true" : "false");
+
+ return;
+}
+
+/* Check to see if this item is shown. Accessor for the
+ internal variable. */
+gboolean
+im_menu_item_shown (ImMenuItem * menuitem)
+{
+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE);
+
+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
+
+ return priv->show;
+}
=== modified file 'src/im-menu-item.h'
--- src/im-menu-item.h 2009-05-26 14:30:37 +0000
+++ src/im-menu-item.h 2009-09-04 22:31:29 +0000
@@ -38,6 +38,7 @@
#define IM_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_MENU_ITEM_TYPE, ImMenuItemClass))
#define IM_MENU_ITEM_SIGNAL_TIME_CHANGED "time-changed"
+#define IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED "attention-changed"
typedef struct _ImMenuItem ImMenuItem;
typedef struct _ImMenuItemClass ImMenuItemClass;
@@ -46,6 +47,7 @@
DbusmenuMenuitemClass parent_class;
void (*time_changed) (glong seconds);
+ void (*attention_changed) (gboolean requestit);
};
struct _ImMenuItem {
@@ -53,8 +55,11 @@
};
GType im_menu_item_get_type (void);
-ImMenuItem * im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gboolean show_time);
+ImMenuItem * im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator);
glong im_menu_item_get_seconds (ImMenuItem * menuitem);
+gboolean im_menu_item_get_attention (ImMenuItem * menuitem);
+void im_menu_item_show (ImMenuItem * menuitem, gboolean show);
+gboolean im_menu_item_shown (ImMenuItem * menuitem);
G_END_DECLS
=== modified file 'src/indicator-messages.c'
--- src/indicator-messages.c 2009-08-27 14:31:43 +0000
+++ src/indicator-messages.c 2009-09-04 20:28:55 +0000
@@ -24,6 +24,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <libdbusmenu-gtk/menu.h>
+#include <libdbusmenu-gtk/menuitem.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-bindings.h>
@@ -41,6 +42,8 @@
static DBusGProxy * icon_proxy = NULL;
+static GtkSizeGroup * indicator_right_group = NULL;
+
static void
attention_changed_cb (DBusGProxy * proxy, gboolean dot, gpointer userdata)
{
@@ -137,6 +140,54 @@
return FALSE;
}
+/* We have a small little menuitem type that handles all
+ of the fun stuff for indicators. Mostly this is the
+ shifting over and putting the icon in with some right
+ side text that'll be determined by the service. */
+static gboolean
+new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
+ /* Note: not checking parent, it's reasonable for it to be NULL */
+
+ GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
+
+ GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
+
+ /* Icon, probably someone's face or avatar on an IM */
+ GtkWidget * icon = gtk_image_new();
+ GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, INDICATOR_MENUITEM_PROP_ICON);
+ if (pixbuf != NULL) {
+ gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pixbuf);
+ }
+ gtk_misc_set_alignment(GTK_MISC(icon), 0.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
+ gtk_widget_show(icon);
+
+ /* Label, probably a username, chat room or mailbox name */
+ GtkWidget * label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_LABEL));
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ /* Usually either the time or the count on the individual
+ item. */
+ GtkWidget * right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT));
+ gtk_size_group_add_widget(indicator_right_group, right);
+ gtk_misc_set_alignment(GTK_MISC(right), 1.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), right, FALSE, FALSE, 0);
+ gtk_widget_show(right);
+
+ gtk_container_add(GTK_CONTAINER(gmi), hbox);
+ gtk_widget_show(hbox);
+
+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+ /* TODO: Handle changes */
+
+ return TRUE;
+}
+
static gboolean
new_launcher_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
{
@@ -207,12 +258,15 @@
return NULL;
}
+ indicator_right_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
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);
+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), INDICATOR_MENUITEM_TYPE, new_indicator_item);
return GTK_MENU(menu);
}
=== modified file 'src/messages-service.c'
--- src/messages-service.c 2009-09-03 19:13:45 +0000
+++ src/messages-service.c 2009-09-05 03:06:42 +0000
@@ -49,7 +49,7 @@
static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data);
static void im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data);
static void resort_menu (DbusmenuMenuitem * menushell);
-static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
+static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data);
static void check_eclipses (AppMenuItem * ai);
static void remove_eclipses (AppMenuItem * ai);
static gboolean build_launcher (gpointer data);
@@ -71,6 +71,8 @@
struct _serverList_t {
IndicateListenerServer * server;
AppMenuItem * menuitem;
+ gboolean attention;
+ guint count;
GList * imList;
};
@@ -112,6 +114,7 @@
IndicateListenerIndicator * indicator;
DbusmenuMenuitem * menuitem;
gulong timechange_cb;
+ gulong attentionchange_cb;
};
static gboolean
@@ -390,6 +393,56 @@
* More code
*/
+/* Goes through all the servers and sees if any of them
+ want attention. If they do, then well we'll give it
+ to them. If they don't, let's not bother the user
+ any, shall we? */
+static void
+check_attention (void)
+{
+ GList * pointer;
+ for (pointer = serverList; pointer != NULL; pointer = g_list_next(pointer)) {
+ serverList_t * slt = (serverList_t *)pointer->data;
+ if (slt->attention) {
+ message_service_dbus_set_attention(dbus_interface, TRUE);
+ return;
+ }
+ }
+ message_service_dbus_set_attention(dbus_interface, FALSE);
+ return;
+}
+
+/* This checks a server listing to see if it should
+ have attention. It can get attention through it's
+ count or by having an indicator that is requestion
+ attention. */
+static void
+server_attention (serverList_t * slt)
+{
+ /* Count, easy yes and out. */
+ if (slt->count > 0) {
+ slt->attention = TRUE;
+ return;
+ }
+
+ /* Check to see if any of the indicators want attention */
+ GList * pointer;
+ for (pointer = slt->imList; pointer != NULL; pointer = g_list_next(pointer)) {
+ imList_t * ilt = (imList_t *)pointer->data;
+ if (im_menu_item_get_attention(IM_MENU_ITEM(ilt->menuitem))) {
+ slt->attention = TRUE;
+ return;
+ }
+ }
+
+ /* Nope, no one */
+ slt->attention = FALSE;
+ return;
+}
+
+/* A new server has been created on the indicate bus.
+ We need to check to see if we like it. And build
+ structures for it if so. */
static void
server_added (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
{
@@ -413,26 +466,34 @@
return;
}
+ /* Build the Menu item */
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);
+ /* Build a possible server structure */
serverList_t * sl_item = g_new0(serverList_t, 1);
sl_item->server = server;
sl_item->menuitem = menuitem;
sl_item->imList = NULL;
+ sl_item->attention = FALSE;
+ sl_item->count = 0;
/* Incase we got an indicator first */
GList * alreadythere = g_list_find_custom(serverList, sl_item, serverList_equal);
if (alreadythere != NULL) {
+ /* Use the one we already had */
g_free(sl_item);
sl_item = (serverList_t *)alreadythere->data;
sl_item->menuitem = menuitem;
serverList = g_list_sort(serverList, serverList_sort);
} else {
+ /* Insert the new one in the list */
serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
}
+ /* Connect the signals up to the menu item */
+ g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), sl_item);
+ g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell);
+
dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
/* Should be prepend ^ */
@@ -442,6 +503,10 @@
return;
}
+/* The name of a server has changed, we probably
+ need to reorder the menu to keep it in alphabetical
+ order. This happens often after we read the destkop
+ file from disk. */
static void
server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data)
{
@@ -451,52 +516,37 @@
return;
}
+/* If the count on the server changes, we need to know
+ whether that should be grabbing attention or not. If
+ it is, we need to reevaluate whether the whole thing
+ should be grabbing attention or not. */
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;
+ serverList_t * slt = (serverList_t *)data;
+ slt->count = count;
+
+ if (count == 0 && slt->attention) {
+ /* Regen based on indicators if the count isn't going to cause it. */
+ server_attention(slt);
+ /* If we're dropping let's see if we're the last. */
+ if (!slt->attention) {
+ check_attention();
+ }
+ }
+
+ if (count != 0 && !slt->attention) {
+ slt->attention = TRUE;
+ /* Let's tell everyone about us! */
message_service_dbus_set_attention(dbus_interface, TRUE);
- 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;
- message_service_dbus_set_attention(dbus_interface, FALSE);
}
return;
}
+/* Respond to the IM entrie's time changing
+ which results in it needing to resort the list
+ and rebuild the menu to match. */
static void
im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data)
{
@@ -506,6 +556,26 @@
return;
}
+/* The IM entrie's request for attention has changed
+ so we need to pass that up the stack. */
+static void
+im_attention_changed (ImMenuItem * imitem, gboolean requestit, gpointer data)
+{
+ serverList_t * sl = (serverList_t *)data;
+
+ if (requestit) {
+ sl->attention = TRUE;
+ message_service_dbus_set_attention(dbus_interface, TRUE);
+ } else {
+ server_attention(sl);
+ if (!sl->attention) {
+ check_attention();
+ }
+ }
+
+ return;
+}
+
static void
server_removed (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
{
@@ -525,7 +595,7 @@
while (sltp->imList) {
imList_t * imitem = (imList_t *)sltp->imList->data;
- indicator_removed(listener, server, imitem->indicator, "message", data);
+ indicator_removed(listener, server, imitem->indicator, data);
}
serverList = g_list_remove(serverList, sltp);
@@ -536,10 +606,14 @@
g_object_unref(G_OBJECT(sltp->menuitem));
}
+ if (sltp->attention) {
+ /* Check to see if this was the server causing the menu item to
+ be lit up. */
+ check_attention();
+ }
+
g_free(sltp);
- /* Simulate a server saying zero to recalculate icon */
- server_count_changed(NULL, 0, NULL);
check_hidden();
return;
@@ -646,8 +720,11 @@
return;
}
+/* Responding to a new indicator showing up on the bus. We
+ need to create a menuitem for it and start populating the
+ internal structures to track it. */
static void
-subtype_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
+indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data)
{
DbusmenuMenuitem * menushell = DBUSMENU_MENUITEM(data);
if (menushell == NULL) {
@@ -655,105 +732,93 @@
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 = DBUSMENU_MENUITEM(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;
-
- dbusmenu_menuitem_foreach(DBUSMENU_MENUITEM(menushell), menushell_foreach_cb, &msl);
- if (msl.found) {
- dbusmenu_menuitem_child_add_position(menushell, DBUSMENU_MENUITEM(menuitem), msl.position);
- } else {
- g_warning("Unable to find server menu item");
- dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(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)
+ imList_t * listItem = g_new0(imList_t, 1);
+ listItem->server = server;
+ listItem->indicator = indicator;
+
+ /* Building the IM Menu Item which is a subclass
+ of DBus Menuitem */
+ ImMenuItem * menuitem = im_menu_item_new(listener, server, indicator);
+ g_object_ref(G_OBJECT(menuitem));
+ listItem->menuitem = DBUSMENU_MENUITEM(menuitem);
+
+ /* Looking for a server entry to attach this indicator
+ to. If we can't find one then we have to build one
+ and attach the indicator to it. */
+ 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;
+ sl_item->attention = FALSE;
+ sl_item->count = 0;
+
+ serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
+ } else {
+ sl_item = (serverList_t *)serverentry->data;
+ }
+
+ /* Added a this entry into the 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);
+ listItem->attentionchange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED, G_CALLBACK(im_attention_changed), sl_item);
+
+ /* Check the length of the list. If we've got more inidactors
+ than we allow. Well. Someone's gotta pay. Sorry. I didn't
+ want to do this, but you did it to yourself. */
+ if (g_list_length(sl_item->imList) > MAX_NUMBER_OF_INDICATORS) {
+ GList * indicatoritem;
+ gint count;
+ for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) {
+ imList_t * im = (imList_t *)indicatoritem->data;
+ im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS);
+ }
+ }
+
+ /* Placing the item into the shell. Look to see if
+ we can find our server and slip in there. Otherwise
+ we'll just append. */
+ menushell_location_t msl;
+ msl.found = FALSE;
+ msl.position = 0;
+ msl.server = server;
+
+ dbusmenu_menuitem_foreach(DBUSMENU_MENUITEM(menushell), menushell_foreach_cb, &msl);
+ if (msl.found) {
+ dbusmenu_menuitem_child_add_position(menushell, DBUSMENU_MENUITEM(menuitem), msl.position);
+ } else {
+ g_warning("Unable to find server menu item");
+ dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
+ }
+
+ return;
+}
+
+/* Process and indicator getting removed from the system. We
+ first need to ensure that it's one of ours and figure out
+ where we put it. When we find all that out we can go through
+ the process of removing the effect it had on the system. */
+static void
+indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, 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;
+ /* Find the server that was related to this item */
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) {
+ /* We didn't care about that server */
return;
}
sl_item = (serverList_t *)serverentry->data;
@@ -771,11 +836,41 @@
menuitem = ilt->menuitem;
}
+ /* If we found a menu item and an imList_t item then
+ we can go ahead and remove it. Otherwise we can
+ skip this and exit. */
if (!removed && menuitem != NULL) {
sl_item->imList = g_list_remove(sl_item->imList, ilt);
g_signal_handler_disconnect(menuitem, ilt->timechange_cb);
+ g_signal_handler_disconnect(menuitem, ilt->attentionchange_cb);
g_free(ilt);
+ if (im_menu_item_get_attention(IM_MENU_ITEM(menuitem)) && im_menu_item_shown(IM_MENU_ITEM(menuitem))) {
+ /* If the removed indicator menu item was asking for
+ attention we need to see if this server should still
+ be asking for attention. */
+ server_attention(sl_item);
+ /* If the server is no longer asking for attention then
+ we need to check if the whole system should be. */
+ if (!sl_item->attention) {
+ check_attention();
+ }
+ }
+
+ if (im_menu_item_shown(IM_MENU_ITEM(menuitem)) && g_list_length(sl_item->imList) >= MAX_NUMBER_OF_INDICATORS) {
+ /* In this case we need to show a different indicator
+ becasue a shown one has left. But we're going to be
+ easy and set all the values. */
+ GList * indicatoritem;
+ gint count;
+ for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) {
+ imList_t * im = (imList_t *)indicatoritem->data;
+ im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS);
+ }
+ }
+
+ /* Hide the item immediately, and then remove it
+ which might take a little longer. */
dbusmenu_menuitem_property_set(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), menuitem);
removed = TRUE;
Follow ups