Merge lp:~ted/indicator-messages/newapi.ubuntu into lp:indicator-messages/0.5

Proposed by David Barth
Status: Rejected
Rejected by: Ted Gould
Proposed branch: lp:~ted/indicator-messages/newapi.ubuntu
Merge into: lp:indicator-messages/0.5
Diff against target: None lines
To merge this branch: bzr merge lp:~ted/indicator-messages/newapi.ubuntu
Reviewer Review Type Date Requested Status
Indicator Applet Developers Pending
Review via email: mp+11317@code.launchpad.net
To post a comment you must log in.
Revision history for this message
David Barth (dbarth) wrote :

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?

Revision history for this message
Ted Gould (ted) wrote :

> Assuming the branch is in a merge'able state.

It's got bugs, but more importantly this is a packaging branch merging into a non-packaging branch. Please don't do that. It'll mess things up in annoying ways :)

Unmerged revisions

148. By Ted Gould

releasing version 0.2.0-0ubuntu3~ppa2~newapi4

147. By Ted Gould

LANG=en_UK Bloody Hell

146. By Ted Gould

releasing version 0.2.0-0ubuntu3~ppa2~newapi3

145. By Ted Gould

Changing items support

144. By Ted Gould

releasing version 0.2.0-0ubuntu3~ppa2~newapi2

143. By Ted Gould

Fix for the changes in libindicate (fixes)

142. By Ted Gould

releasing version 0.2.0-0ubuntu3~ppa2~newapi1

141. By Ted Gould

Merging in changes for the new libindicate API

140. By Ted Gould

releasing version 0.2.0-0ubuntu3~ppa1

139. By Ted Gould

Bumping version after ~ubuntu-desktop merge.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '.bzr-builddeb'
2=== added file '.bzr-builddeb/default.conf'
3--- .bzr-builddeb/default.conf 1970-01-01 00:00:00 +0000
4+++ .bzr-builddeb/default.conf 2009-03-19 11:22:21 +0000
5@@ -0,0 +1,2 @@
6+[BUILDDEB]
7+merge = True
8
9=== modified file 'configure.ac'
10--- configure.ac 2009-09-03 19:06:22 +0000
11+++ configure.ac 2009-09-04 20:37:59 +0000
12@@ -34,7 +34,6 @@
13 gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION
14 indicator >= $INDICATOR_REQUIRED_VERSION
15 indicate >= $INDICATE_REQUIRED_VERSION
16- indicate-gtk >= $INDICATE_REQUIRED_VERSION
17 dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION)
18 AC_SUBST(APPLET_CFLAGS)
19 AC_SUBST(APPLET_LIBS)
20
21=== added directory 'debian'
22=== added file 'debian/changelog'
23--- debian/changelog 1970-01-01 00:00:00 +0000
24+++ debian/changelog 2009-09-05 16:44:38 +0000
25@@ -0,0 +1,178 @@
26+indicator-messages (0.2.0-0ubuntu3~ppa2~newapi2) karmic; urgency=low
27+
28+ * Fix for the changes in libindicate (fixes)
29+
30+ -- Ted Gould <ted@ubuntu.com> Sat, 05 Sep 2009 11:44:34 -0500
31+
32+indicator-messages (0.2.0-0ubuntu3~ppa2~newapi1) karmic; urgency=low
33+
34+ * Merging in changes for the new libindicate API
35+
36+ -- Ted Gould <ted@ubuntu.com> Sat, 05 Sep 2009 11:13:51 -0500
37+
38+indicator-messages (0.2.0-0ubuntu3~ppa1) karmic; urgency=low
39+
40+ * Bumping version after ~ubuntu-desktop merge.
41+
42+ -- Ted Gould <ted@ubuntu.com> Fri, 04 Sep 2009 13:56:06 -0500
43+
44+indicator-messages (0.2.0-0ubuntu1~ppa3) karmic; urgency=low
45+
46+ * Upstream usage of new Dbusmenu 0.1.1 defines.
47+ * debian/control: Increasing Dbusmenu dependencies.
48+
49+ -- Ted Gould <ted@ubuntu.com> Fri, 04 Sep 2009 13:50:50 -0500
50+
51+indicator-messages (0.2.0-0ubuntu1~ppa2) karmic; urgency=low
52+
53+ * Upstream update to dbusmenu dependency.
54+ * debian/control: Adding dependency information for libdbusmenu
55+ to say >= 0.1.0 to match upstream build system.
56+
57+ -- Ted Gould <ted@ubuntu.com> Thu, 27 Aug 2009 14:01:03 -0500
58+
59+indicator-messages (0.2.0-0ubuntu2) karmic; urgency=low
60+
61+ * debian/control
62+ - Bump build depends on dbusmenu to 0.1.0
63+
64+ -- Ken VanDine <ken.vandine@canonical.com> Thu, 27 Aug 2009 21:14:46 +0200
65+
66+indicator-messages (0.2.0-0ubuntu1) karmic; urgency=low
67+
68+ [ Ted Gould ]
69+ * Upstream version 0.2.0
70+ * debian/control: Adding dependency information for libdbusmenu
71+ to say >= 0.0.2 to match upstream build system.
72+ * debian/watch: Changing to use indicator-messages project.
73+
74+ [ Martin Pitt ]
75+ * debian/control: Update Vcs-Bzr: for new branch location.
76+
77+ -- Ted Gould <ted@ubuntu.com> Thu, 27 Aug 2009 20:46:27 +0200
78+
79+indicator-messages (0.2.0~bzr124-0ubuntu1) karmic; urgency=low
80+
81+ * Update to fix build issue
82+
83+ -- Sebastien Bacher <seb128@ubuntu.com> Fri, 07 Aug 2009 17:12:40 +0100
84+
85+indicator-messages (0.2.0~bzr121-0ubuntu3) karmic; urgency=low
86+
87+ * Fix to dereference the application menu items correctly so that
88+ the signal handlers are dropped as well. (lp: #410251)
89+
90+ -- Ted Gould <ted@ubuntu.com> Wed, 05 Aug 2009 19:00:31 +0100
91+
92+indicator-messages (0.2.0~bzr121-0ubuntu2) karmic; urgency=low
93+
94+ * Run autogen.sh before upload
95+
96+ -- Jonathan Riddell <jriddell@ubuntu.com> Wed, 05 Aug 2009 00:42:39 +0100
97+
98+indicator-messages (0.2.0~bzr121-0ubuntu1) karmic; urgency=low
99+
100+ [ Ted Gould ]
101+ * debian/control: Adding in a build dep on libindicate-gtk-dev
102+ * Changes for the changing libindicate stuff.
103+ * Merge in the dbusmenu changes from the dbusmenu branch
104+ * debian/control: Adding in a build dependency on libdbusmenu-glib and
105+ libdbusmenu-gtk to catch up with the merge.
106+
107+ -- Jonathan Riddell <jriddell@ubuntu.com> Wed, 05 Aug 2009 00:21:50 +0100
108+
109+indicator-messages (0.2.0~bzr120-0ubuntu1) jaunty; urgency=low
110+
111+ * Fix to track the timer. (LP: #365187)
112+
113+ -- Ted Gould <ted@ubuntu.com> Wed, 13 May 2009 09:56:20 -0500
114+
115+indicator-messages (0.2.0~bzr119-0ubuntu1) jaunty; urgency=low
116+
117+ * Upstream update
118+
119+ -- Ted Gould <ted@ubuntu.com> Wed, 22 Apr 2009 23:34:21 -0500
120+
121+indicator-messages (0.2.0~bzr116-0ubuntu3) jaunty; urgency=low
122+
123+ * debian/rules: Adding a rule to remove the .la/.a clutter
124+
125+ -- Ted Gould <ted@ubuntu.com> Wed, 22 Apr 2009 16:46:59 -0500
126+
127+indicator-messages (0.2.0~bzr116-0ubuntu2) jaunty; urgency=low
128+
129+ * debian/control: libindicator-dev to ~bzr301
130+
131+ -- Ted Gould <ted@ubuntu.com> Wed, 22 Apr 2009 15:58:45 -0500
132+
133+indicator-messages (0.2.0~bzr116-0ubuntu1) jaunty; urgency=low
134+
135+ * Upstream release
136+ * Bug fixes
137+ * Update API to new libindicator
138+ * debian/control: Adding new dependency on libindicator-dev
139+
140+ -- Ted Gould <ted@ubuntu.com> Wed, 22 Apr 2009 15:45:21 -0500
141+
142+indicator-messages (0.1.6-0ubuntu1) jaunty; urgency=low
143+
144+ * New upstream version
145+ * Patch from Cody Russell to fix LP: #359018 by correctly implementing
146+ the finalize functions.
147+
148+ -- Ted Gould <ted@ubuntu.com> Tue, 14 Apr 2009 11:32:00 +0200
149+
150+indicator-messages (0.1.5-0ubuntu1) jaunty; urgency=low
151+
152+ * New upstream version
153+ * Fixes the lifecycle of the various structures tracking the messages
154+ and applications. Fixing bugs like (LP: #355616) (LP: #352881)
155+ * Fixes the visual appearance by setting the widget name to grab the
156+ style settings from the main applet. (LP: #351979)
157+ * debian/control: Upgrading dependency on libindicate-dev to 0.1.5 or
158+ higher as the new version requires that.
159+
160+ -- Ted Gould <ted@ubuntu.com> Fri, 03 Apr 2009 16:32:49 -0500
161+
162+indicator-messages (0.1.4-0ubuntu1) jaunty; urgency=low
163+
164+ * New upstream version
165+ * Adding the display of indicators that are login messages coming from
166+ other applications. (LP: #345494)
167+ * Making all times displayed for IM messages relative instead of
168+ absolute. (LP: #346345)
169+ * Cleaning up the server removal code. May fix (LP: #345599), I can't
170+ recreate it anymore afterwards.
171+
172+ -- Ted Gould <ted@ubuntu.com> Mon, 30 Mar 2009 09:40:40 +0200
173+
174+indicator-messages (0.1.3-0ubuntu1) jaunty; urgency=low
175+
176+ [ Ted Gould ]
177+ * New upstream version.
178+ - Now changes the icon based on non-IM indicators so that Evolution
179+ works much better. (LP: #342480)
180+ - Now the menu items are in a predictable order, alphabetical.
181+ - The Messages for a particular client (i.e. Pidgin) are grouped with
182+ the client they're associated with.
183+ - Adjusting the icon size to match the new one in the Human theme.
184+ - Adjusting the build so that all the different libraries are not
185+ built in a versioned manner. Now it's just one .so, which is
186+ what it should have been originally.
187+
188+ [ Martin Pitt ]
189+ * Add debian/watch.
190+ * Add bzr-builddeb configuration.
191+ * debian/copyright: Fix download location.
192+
193+ -- Martin Pitt <martin.pitt@ubuntu.com> Thu, 19 Mar 2009 12:23:17 +0100
194+
195+indicator-messages (0.1-0ubuntu1) jaunty; urgency=low
196+
197+ * Initial release, based on DX team's PPA packaging branch.
198+ (lp:~indicator-applet-developers/indicator-applet/messages-packaging)
199+ * debian/control: Add Homepage:, Vcs-Bzr:, and fix package
200+ description.
201+ * debian/copyright: Properly describe license.
202+
203+ -- Martin Pitt <martin.pitt@ubuntu.com> Tue, 17 Feb 2009 11:35:38 +0100
204
205=== added file 'debian/control'
206--- debian/control 1970-01-01 00:00:00 +0000
207+++ debian/control 2009-09-04 18:54:25 +0000
208@@ -0,0 +1,29 @@
209+Source: indicator-messages
210+Section: gnome
211+Priority: optional
212+Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>
213+Build-Depends: debhelper (>= 5.0),
214+ cdbs (>= 0.4.41),
215+ libgtk2.0-dev (>= 2.12.0),
216+ libdbus-glib-1-dev,
217+ gnome-doc-utils,
218+ scrollkeeper,
219+ intltool,
220+ libindicate-dev (>= 0.2.0~bzr298),
221+ libindicate-gtk-dev (>= 0.2.0~bzr298),
222+ libindicator-dev (>= 0.2.0~bzr301),
223+ libdbusmenu-gtk-dev (>= 0.1.1),
224+ libdbusmenu-glib-dev (>= 0.1.1)
225+Standards-Version: 3.8.0
226+Homepage: https://launchpad.net/indicator-applet
227+Vcs-Bzr: http://bazaar.launchpad.net/~ubuntu-desktop/indicator-messages/ubuntu
228+
229+Package: indicator-messages
230+Architecture: any
231+Depends: ${shlibs:Depends}, ${misc:Depends}, indicator-applet
232+Description: GNOME panel indicator applet for messages
233+ indicator-applet is an applet to display information from
234+ various applications consistently in the GNOME panel.
235+ .
236+ This package provides support for messaging applications.
237+
238
239=== added file 'debian/copyright'
240--- debian/copyright 1970-01-01 00:00:00 +0000
241+++ debian/copyright 2009-03-19 11:22:57 +0000
242@@ -0,0 +1,33 @@
243+This package was debianized by Ted Gould <ted@canonical.com> on
244+Wed, 11 Feb 2009 15:41:06 -0600.
245+
246+It was downloaded from <http://launchpad.net/indicator-applet/>
247+
248+Upstream Author:
249+
250+ Ted Gould <ted@canonical.com>
251+
252+Copyright:
253+
254+ Copyright (C) 2009 Canonical Ltd.
255+
256+License:
257+
258+ This program is free software; you can redistribute it and/or modify
259+ it under the terms of the GNU General Public License as published by
260+ the Free Software Foundation, version 3 of the License.
261+
262+ This program is distributed in the hope that it will be useful,
263+ but WITHOUT ANY WARRANTY; without even the implied warranty of
264+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
265+ GNU General Public License for more details.
266+
267+ You should have received a copy of the GNU General Public License
268+ along with this program; if not, write to the Free Software
269+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
270+
271+On Debian systems, the complete text of the GNU General
272+Public License can be found in `/usr/share/common-licenses/GPL-3'.
273+
274+The Debian packaging is (C) 2009, Canonical Ltd. and
275+is licensed under the GPLv3, see `/usr/share/common-licenses/GPL-3'.
276
277=== added file 'debian/rules'
278--- debian/rules 1970-01-01 00:00:00 +0000
279+++ debian/rules 2009-04-22 21:46:57 +0000
280@@ -0,0 +1,12 @@
281+#!/usr/bin/make -f
282+
283+include /usr/share/cdbs/1/rules/debhelper.mk
284+include /usr/share/cdbs/1/class/gnome.mk
285+
286+DEB_CONFIGURE_EXTRA_FLAGS += --disable-scrollkeeper
287+LDFLAGS += -Wl,-z,defs -Wl,--as-needed
288+
289+binary-install/indicator-messages::
290+ # remove .a/.la clutter
291+ rm -f debian/$(cdbs_curpkg)/usr/lib/indicators/*/*.a
292+ rm -f debian/$(cdbs_curpkg)/usr/lib/indicators/*/*.la
293
294=== added file 'debian/watch'
295--- debian/watch 1970-01-01 00:00:00 +0000
296+++ debian/watch 2009-08-27 18:10:28 +0000
297@@ -0,0 +1,2 @@
298+version=3
299+http://launchpad.net/indicator-messages/+download .*/indicator-messages-([0-9.]+)\.tar\.gz
300
301=== modified file 'src/app-menu-item.c'
302--- src/app-menu-item.c 2009-08-26 21:47:55 +0000
303+++ src/app-menu-item.c 2009-09-05 16:43:36 +0000
304@@ -27,6 +27,7 @@
305 #include <glib/gi18n.h>
306 #include <gio/gdesktopappinfo.h>
307 #include "app-menu-item.h"
308+#include "dbus-data.h"
309
310 enum {
311 COUNT_CHANGED,
312@@ -47,7 +48,6 @@
313 GAppInfo * appinfo;
314 gchar * desktop;
315 guint unreadcount;
316- gboolean count_on_label;
317 };
318
319 #define APP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_MENU_ITEM_TYPE, AppMenuItemPrivate))
320@@ -58,14 +58,12 @@
321 static void app_menu_item_dispose (GObject *object);
322 static void app_menu_item_finalize (GObject *object);
323 static void activate_cb (AppMenuItem * self, gpointer data);
324-static void type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data);
325+static void count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data);
326+static void count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data);
327 static void desktop_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data);
328-static void indicator_added_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
329-static void indicator_removed_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
330 static void update_label (AppMenuItem * self);
331
332-
333-
334+/* GObject Boilerplate */
335 G_DEFINE_TYPE (AppMenuItem, app_menu_item, DBUSMENU_TYPE_MENUITEM);
336
337 static void
338@@ -108,8 +106,6 @@
339 priv->appinfo = NULL;
340 priv->desktop = NULL;
341 priv->unreadcount = 0;
342- priv->count_on_label = FALSE;
343-
344
345 return;
346 }
347@@ -120,9 +116,6 @@
348 AppMenuItem * self = APP_MENU_ITEM(object);
349 AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
350
351- g_signal_handlers_disconnect_by_func(G_OBJECT(priv->listener), G_CALLBACK(indicator_added_cb), self);
352- g_signal_handlers_disconnect_by_func(G_OBJECT(priv->listener), G_CALLBACK(indicator_removed_cb), self);
353-
354 g_object_unref(priv->listener);
355
356 G_OBJECT_CLASS (app_menu_item_parent_class)->dispose (object);
357@@ -158,63 +151,38 @@
358
359 AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
360
361+ /* Copy the listener so we can use it later */
362 priv->listener = listener;
363 g_object_ref(G_OBJECT(listener));
364+
365+ /* Can not ref as not real GObject */
366 priv->server = server;
367- /* Can not ref as not real GObject */
368-
369- g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added_cb), self);
370- g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_CALLBACK(indicator_removed_cb), self);
371-
372- indicate_listener_server_get_type(listener, server, type_cb, self);
373+
374+ /* Set up listener signals */
375+ g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_SERVER_COUNT_CHANGED, G_CALLBACK(count_changed), self);
376+
377+ /* Get the values we care about from the server */
378 indicate_listener_server_get_desktop(listener, server, desktop_cb, self);
379+ indicate_listener_server_get_count(listener, server, count_cb, self);
380
381 g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL);
382
383 indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_DISPLAY);
384 indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_SIGNAL);
385+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_COUNT);
386+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_DISPLAY);
387+ indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_SIGNAL);
388+ indicate_listener_set_server_max_indicators(listener, server, MAX_NUMBER_OF_INDICATORS);
389
390 return self;
391 }
392
393-static void
394-type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data)
395-{
396- AppMenuItem * self = APP_MENU_ITEM(data);
397- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
398-
399- if (priv->type != NULL) {
400- g_free(priv->type);
401- priv->type = NULL;
402- }
403-
404- if (value == NULL) {
405- g_warning("Type value is NULL, that shouldn't really happen");
406- return;
407- }
408-
409- priv->type = g_strdup(value);
410-
411- if (!(!g_strcmp0(priv->type, "message.instant") || !g_strcmp0(priv->type, "message.micro") || !g_strcmp0(priv->type, "message.im"))) {
412- /* For IM and Microblogging we want the individual items, not a count */
413- priv->count_on_label = TRUE;
414- update_label(self);
415-
416- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_COUNT);
417- } else {
418- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_DISPLAY);
419- indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_SIGNAL);
420- }
421-
422- return;
423-}
424-
425 static void
426 update_label (AppMenuItem * self)
427 {
428 AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
429
430- if (priv->count_on_label && !priv->unreadcount < 1) {
431+ if (priv->unreadcount > 0) {
432 /* TRANSLATORS: This is the name of the program and the number of indicators. So it
433 would read something like "Mail Client (5)" */
434 gchar * label = g_strdup_printf(_("%s (%d)"), app_menu_item_get_name(self), priv->unreadcount);
435@@ -227,6 +195,38 @@
436 return;
437 }
438
439+/* Callback to the signal that the server count
440+ has changed to a new value. This checks to see if
441+ it's actually changed and if so signals everyone and
442+ updates the label. */
443+static void
444+count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data)
445+{
446+ AppMenuItem * self = APP_MENU_ITEM(data);
447+ AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self);
448+
449+ if (priv->unreadcount != count) {
450+ priv->unreadcount = count;
451+ update_label(self);
452+ g_signal_emit(G_OBJECT(self), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
453+ }
454+
455+ return;
456+}
457+
458+/* Callback for getting the count property off
459+ of the server. */
460+static void
461+count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data)
462+{
463+ count_changed(listener, server, value, data);
464+ return;
465+}
466+
467+/* Callback for when we ask the server for the path
468+ to it's desktop file. We then turn it into an
469+ app structure and start sucking data out of it.
470+ Mostly the name. */
471 static void
472 desktop_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data)
473 {
474@@ -268,46 +268,6 @@
475 return;
476 }
477
478-static void
479-indicator_added_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
480-{
481- g_return_if_fail(IS_APP_MENU_ITEM(data));
482- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(data);
483-
484- if (g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_SERVER_DBUS_NAME(priv->server))) {
485- /* Not us */
486- return;
487- }
488-
489- priv->unreadcount++;
490-
491- update_label(APP_MENU_ITEM(data));
492- g_signal_emit(G_OBJECT(data), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
493-
494- return;
495-}
496-
497-static void
498-indicator_removed_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
499-{
500- AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(data);
501-
502- if (g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_SERVER_DBUS_NAME(priv->server))) {
503- /* Not us */
504- return;
505- }
506-
507- /* Should never happen, but let's have some protection on that */
508- if (priv->unreadcount > 0) {
509- priv->unreadcount--;
510- }
511-
512- update_label(APP_MENU_ITEM(data));
513- g_signal_emit(G_OBJECT(data), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE);
514-
515- return;
516-}
517-
518 guint
519 app_menu_item_get_count (AppMenuItem * appitem)
520 {
521
522=== modified file 'src/dbus-data.h'
523--- src/dbus-data.h 2009-08-27 01:06:09 +0000
524+++ src/dbus-data.h 2009-09-04 22:14:23 +0000
525@@ -12,4 +12,15 @@
526 #define LAUNCHER_MENUITEM_PROP_APP_NAME "application-name"
527 #define LAUNCHER_MENUITEM_PROP_APP_DESC "application-description"
528
529+#define APPLICATION_MENUITEM_TYPE "application-item"
530+#define APPLICATION_MENUITEM_PROP_NAME "app-name"
531+#define APPLICATION_MENUITEM_PROP_COUNT "app-count"
532+
533+#define INDICATOR_MENUITEM_TYPE "indicator-item"
534+#define INDICATOR_MENUITEM_PROP_LABEL "indicator-label"
535+#define INDICATOR_MENUITEM_PROP_ICON "indicator-icon"
536+#define INDICATOR_MENUITEM_PROP_RIGHT "right-side-text"
537+
538+#define MAX_NUMBER_OF_INDICATORS 7
539+
540 #endif /* __DBUS_DATA_H__ */
541
542=== modified file 'src/im-menu-item.c'
543--- src/im-menu-item.c 2009-09-04 14:02:34 +0000
544+++ src/im-menu-item.c 2009-09-04 22:31:29 +0000
545@@ -25,12 +25,15 @@
546
547 #include <glib/gi18n.h>
548 #include <libdbusmenu-glib/client.h>
549-#include <libindicate-gtk/indicator.h>
550-#include <libindicate-gtk/listener.h>
551+#include <libindicate/indicator.h>
552+#include <libindicate/indicator-messages.h>
553+#include <libindicate/listener.h>
554 #include "im-menu-item.h"
555+#include "dbus-data.h"
556
557 enum {
558 TIME_CHANGED,
559+ ATTENTION_CHANGED,
560 LAST_SIGNAL
561 };
562
563@@ -45,8 +48,10 @@
564 IndicateListenerIndicator * indicator;
565
566 glong seconds;
567- gboolean show_time;
568+ gchar * count;
569 gulong indicator_changed;
570+ gboolean attention;
571+ gboolean show;
572
573 guint time_update_min;
574 };
575@@ -81,7 +86,6 @@
576 static void indicator_modified_cb (IndicateListener * listener,
577 IndicateListenerServer * server,
578 IndicateListenerIndicator * indicator,
579- gchar * type,
580 gchar * property,
581 ImMenuItem * self);
582
583@@ -104,6 +108,13 @@
584 NULL, NULL,
585 g_cclosure_marshal_VOID__LONG,
586 G_TYPE_NONE, 1, G_TYPE_LONG);
587+ signals[ATTENTION_CHANGED] = g_signal_new(IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED,
588+ G_TYPE_FROM_CLASS(klass),
589+ G_SIGNAL_RUN_LAST,
590+ G_STRUCT_OFFSET (ImMenuItemClass, attention_changed),
591+ NULL, NULL,
592+ g_cclosure_marshal_VOID__BOOLEAN,
593+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
594
595 return;
596 }
597@@ -147,20 +158,25 @@
598 G_OBJECT_CLASS (im_menu_item_parent_class)->finalize (object);
599 }
600
601+/* Call back for getting icon data. It just passes it along
602+ to the indicator so that it can visualize it. Not our problem. */
603 static void
604 icon_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
605 {
606- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM_PROP_ICON_DATA, propertydata);
607+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(data), INDICATOR_MENUITEM_PROP_ICON, propertydata);
608 return;
609 }
610
611+/* This function takes the time and turns it into the appropriate
612+ string to put on the right side of the menu item. Of course it
613+ doesn't do that if there is a count set. If there's a count then
614+ it gets that space. */
615 static void
616 update_time (ImMenuItem * self)
617 {
618 ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
619
620- if (!priv->show_time) {
621- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "right-column", "");
622+ if (priv->count != NULL) {
623 return;
624 }
625
626@@ -191,13 +207,15 @@
627 }
628
629 if (timestring != NULL) {
630- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "right-column", "");
631+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, timestring);
632 g_free(timestring);
633 }
634
635 return;
636 }
637
638+/* This is a wrapper around update_time that matches the prototype
639+ needed to make this a timer callback. Silly. */
640 static gboolean
641 time_update_cb (gpointer data)
642 {
643@@ -208,6 +226,10 @@
644 return TRUE;
645 }
646
647+/* Yet another time function. This one takes the time as formated as
648+ we get it from libindicate and turns it into the seconds that we're
649+ looking for. It should only be called once at the init with a new
650+ indicator and again when the value changes. */
651 static void
652 time_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, GTimeVal * propertydata, gpointer data)
653 {
654@@ -238,26 +260,106 @@
655 return;
656 }
657
658+/* Callback from libindicate that is for getting the sender information
659+ on a particular indicator. */
660 static void
661 sender_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
662 {
663 g_debug("Got Sender Information");
664 ImMenuItem * self = IM_MENU_ITEM(data);
665- if (self == NULL) {
666- g_error("Menu Item callback called without a menu item");
667- return;
668- }
669-
670- if (property == NULL || g_strcmp0(property, "sender")) {
671- g_warning("Sender callback called without being sent the sender. We got '%s' with value '%s'.", property, propertydata);
672- return;
673- }
674-
675- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, propertydata);
676-
677- return;
678-}
679-
680+
681+ /* Our data should be right */
682+ g_return_if_fail(self != NULL);
683+ /* We should have a property name */
684+ g_return_if_fail(property != NULL);
685+ /* The Property should be sender or name */
686+ g_return_if_fail(!g_strcmp0(property, "sender") || !g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME));
687+
688+ /* We might get the sender variable returning a
689+ null string as it doesn't exist on newer clients
690+ but we don't want to listen to that. */
691+ if (!g_strcmp0(property, "sender") && property[0] == '\0') {
692+ return;
693+ }
694+
695+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_LABEL, propertydata);
696+
697+ return;
698+}
699+
700+/* Callback saying that the count is updated, we need to either put
701+ that on the menu item or just remove it if the count is gone. If
702+ that's the case we can update time. */
703+static void
704+count_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
705+{
706+ g_debug("Got Count Information");
707+ ImMenuItem * self = IM_MENU_ITEM(data);
708+
709+ /* Our data should be right */
710+ g_return_if_fail(self != NULL);
711+ /* We should have a property name */
712+ g_return_if_fail(property != NULL);
713+ /* The Property should be count */
714+ g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT));
715+
716+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
717+
718+ if (propertydata == NULL || propertydata[0] == '\0') {
719+ /* The count is either being unset or it was never
720+ set in the first place. */
721+ if (priv->count != NULL) {
722+ g_free(priv->count);
723+ priv->count = NULL;
724+ update_time(self);
725+ }
726+ return;
727+ }
728+
729+ if (priv->count != NULL) {
730+ g_free(priv->count);
731+ }
732+
733+ priv->count = g_strdup_printf("(%s)", propertydata);
734+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, priv->count);
735+
736+ return;
737+}
738+
739+/* This is getting the attention variable that's looking at whether
740+ this indicator should be calling for attention or not. If we are,
741+ we need to signal that. */
742+static void
743+attention_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
744+{
745+ g_debug("Got Attention Information");
746+ ImMenuItem * self = IM_MENU_ITEM(data);
747+
748+ /* Our data should be right */
749+ g_return_if_fail(self != NULL);
750+ /* We should have a property name */
751+ g_return_if_fail(property != NULL);
752+ /* The Property should be count */
753+ g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION));
754+
755+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
756+
757+ gboolean wantit;
758+ if (propertydata == NULL || propertydata[0] == '\0' || !g_strcmp0(propertydata, "false")) {
759+ wantit = FALSE;
760+ } else {
761+ wantit = TRUE;
762+ }
763+
764+ if (priv->attention != wantit) {
765+ priv->attention = wantit;
766+ g_signal_emit(G_OBJECT(self), signals[ATTENTION_CHANGED], 0, wantit, TRUE);
767+ }
768+
769+ return;
770+}
771+
772+/* Callback when the item gets clicked on from the Messaging Menu */
773 static void
774 activate_cb (ImMenuItem * self, gpointer data)
775 {
776@@ -266,8 +368,10 @@
777 indicate_listener_display(priv->listener, priv->server, priv->indicator);
778 }
779
780+/* Callback when a property gets modified. It figures out which one
781+ got modified and notifies the appropriate person. */
782 void
783-indicator_modified_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gchar * property, ImMenuItem * self)
784+indicator_modified_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, ImMenuItem * self)
785 {
786 ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self);
787
788@@ -275,19 +379,29 @@
789 if (INDICATE_LISTENER_INDICATOR_ID(indicator) != INDICATE_LISTENER_INDICATOR_ID(priv->indicator)) return;
790 if (server != priv->server) return;
791
792- if (!g_strcmp0(property, "sender")) {
793+ /* Determine which property has been changed and request the
794+ value go to the appropriate callback. */
795+ if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME)) {
796+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self);
797+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_TIME)) {
798+ indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self);
799+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ICON)) {
800+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self);
801+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT)) {
802+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self);
803+ } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION)) {
804+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self);
805+ } else if (!g_strcmp0(property, "sender")) {
806+ /* This is a compatibility string with v1 and should be removed */
807+ g_debug("Indicator is using 'sender' property which is a v1 string.");
808 indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self);
809- } else if (!g_strcmp0(property, "time")) {
810- indicate_listener_get_property_time(listener, server, indicator, "time", time_cb, self);
811- } else if (!g_strcmp0(property, "icon")) {
812- indicate_listener_get_property(listener, server, indicator, "icon", icon_cb, self);
813 }
814
815 return;
816 }
817
818 ImMenuItem *
819-im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gboolean show_time)
820+im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator)
821 {
822 ImMenuItem * self = g_object_new(IM_MENU_ITEM_TYPE, NULL);
823
824@@ -296,14 +410,21 @@
825 priv->listener = listener;
826 priv->server = server;
827 priv->indicator = indicator;
828- priv->show_time = show_time;
829+ priv->count = NULL;
830 priv->time_update_min = 0;
831-
832- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "type", DBUSMENU_CLIENT_TYPES_IMAGE);
833-
834+ priv->attention = FALSE;
835+ priv->show = TRUE;
836+
837+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), "type", INDICATOR_MENUITEM_TYPE);
838+
839+ indicate_listener_displayed(listener, server, indicator, TRUE);
840+
841+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self);
842+ indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self);
843+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self);
844+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self);
845+ indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self);
846 indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self);
847- indicate_listener_get_property_time(listener, server, indicator, "time", time_cb, self);
848- indicate_listener_get_property(listener, server, indicator, "icon", icon_cb, self);
849
850 g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL);
851 priv->indicator_changed = g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED, G_CALLBACK(indicator_modified_cb), self);
852@@ -311,9 +432,65 @@
853 return self;
854 }
855
856+/* Gets the number of seconds for the creator
857+ of this item. */
858 glong
859 im_menu_item_get_seconds (ImMenuItem * menuitem)
860 {
861+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), 0);
862+
863 ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
864 return priv->seconds;
865 }
866+
867+/* Gets whether or not this indicator item is
868+ asking for attention or not. */
869+gboolean
870+im_menu_item_get_attention (ImMenuItem * menuitem)
871+{
872+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE);
873+
874+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
875+ return priv->attention;
876+}
877+
878+/* This takes care of items that need to be hidden, this is
879+ usually because they go over the count of allowed indicators.
880+ Which is more than a little bit silly. We shouldn't do that.
881+ But we need to enforce it to save users against bad apps. */
882+void
883+im_menu_item_show (ImMenuItem * menuitem, gboolean show)
884+{
885+ g_return_if_fail(IS_IM_MENU_ITEM(menuitem));
886+
887+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
888+
889+ if (priv->show == show) {
890+ return;
891+ }
892+
893+ priv->show = show;
894+ /* Tell the app what we're doing to it. If it's being
895+ punished it needs to know about it. */
896+ indicate_listener_displayed(priv->listener, priv->server, priv->indicator, priv->show);
897+ if (priv->attention) {
898+ /* If we were asking for attention we can ask for it
899+ again if we're being shown, otherwise no. */
900+ g_signal_emit(G_OBJECT(menuitem), signals[ATTENTION_CHANGED], 0, priv->show, TRUE);
901+ }
902+ dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, priv->show ? "true" : "false");
903+
904+ return;
905+}
906+
907+/* Check to see if this item is shown. Accessor for the
908+ internal variable. */
909+gboolean
910+im_menu_item_shown (ImMenuItem * menuitem)
911+{
912+ g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE);
913+
914+ ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem);
915+
916+ return priv->show;
917+}
918
919=== modified file 'src/im-menu-item.h'
920--- src/im-menu-item.h 2009-05-26 14:30:37 +0000
921+++ src/im-menu-item.h 2009-09-04 22:31:29 +0000
922@@ -38,6 +38,7 @@
923 #define IM_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_MENU_ITEM_TYPE, ImMenuItemClass))
924
925 #define IM_MENU_ITEM_SIGNAL_TIME_CHANGED "time-changed"
926+#define IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED "attention-changed"
927
928 typedef struct _ImMenuItem ImMenuItem;
929 typedef struct _ImMenuItemClass ImMenuItemClass;
930@@ -46,6 +47,7 @@
931 DbusmenuMenuitemClass parent_class;
932
933 void (*time_changed) (glong seconds);
934+ void (*attention_changed) (gboolean requestit);
935 };
936
937 struct _ImMenuItem {
938@@ -53,8 +55,11 @@
939 };
940
941 GType im_menu_item_get_type (void);
942-ImMenuItem * im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gboolean show_time);
943+ImMenuItem * im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator);
944 glong im_menu_item_get_seconds (ImMenuItem * menuitem);
945+gboolean im_menu_item_get_attention (ImMenuItem * menuitem);
946+void im_menu_item_show (ImMenuItem * menuitem, gboolean show);
947+gboolean im_menu_item_shown (ImMenuItem * menuitem);
948
949 G_END_DECLS
950
951
952=== modified file 'src/indicator-messages.c'
953--- src/indicator-messages.c 2009-08-27 14:31:43 +0000
954+++ src/indicator-messages.c 2009-09-04 20:28:55 +0000
955@@ -24,6 +24,7 @@
956 #include <glib.h>
957 #include <gtk/gtk.h>
958 #include <libdbusmenu-gtk/menu.h>
959+#include <libdbusmenu-gtk/menuitem.h>
960 #include <dbus/dbus-glib.h>
961 #include <dbus/dbus-glib-bindings.h>
962
963@@ -41,6 +42,8 @@
964
965 static DBusGProxy * icon_proxy = NULL;
966
967+static GtkSizeGroup * indicator_right_group = NULL;
968+
969 static void
970 attention_changed_cb (DBusGProxy * proxy, gboolean dot, gpointer userdata)
971 {
972@@ -137,6 +140,54 @@
973 return FALSE;
974 }
975
976+/* We have a small little menuitem type that handles all
977+ of the fun stuff for indicators. Mostly this is the
978+ shifting over and putting the icon in with some right
979+ side text that'll be determined by the service. */
980+static gboolean
981+new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
982+{
983+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
984+ g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
985+ /* Note: not checking parent, it's reasonable for it to be NULL */
986+
987+ GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
988+
989+ GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
990+
991+ /* Icon, probably someone's face or avatar on an IM */
992+ GtkWidget * icon = gtk_image_new();
993+ GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, INDICATOR_MENUITEM_PROP_ICON);
994+ if (pixbuf != NULL) {
995+ gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pixbuf);
996+ }
997+ gtk_misc_set_alignment(GTK_MISC(icon), 0.0, 0.5);
998+ gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
999+ gtk_widget_show(icon);
1000+
1001+ /* Label, probably a username, chat room or mailbox name */
1002+ GtkWidget * label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_LABEL));
1003+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1004+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
1005+ gtk_widget_show(label);
1006+
1007+ /* Usually either the time or the count on the individual
1008+ item. */
1009+ GtkWidget * right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT));
1010+ gtk_size_group_add_widget(indicator_right_group, right);
1011+ gtk_misc_set_alignment(GTK_MISC(right), 1.0, 0.5);
1012+ gtk_box_pack_start(GTK_BOX(hbox), right, FALSE, FALSE, 0);
1013+ gtk_widget_show(right);
1014+
1015+ gtk_container_add(GTK_CONTAINER(gmi), hbox);
1016+ gtk_widget_show(hbox);
1017+
1018+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
1019+ /* TODO: Handle changes */
1020+
1021+ return TRUE;
1022+}
1023+
1024 static gboolean
1025 new_launcher_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
1026 {
1027@@ -207,12 +258,15 @@
1028 return NULL;
1029 }
1030
1031+ indicator_right_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1032+
1033 g_idle_add(setup_icon_proxy, NULL);
1034
1035 DbusmenuGtkMenu * menu = dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT);
1036 DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu);
1037
1038 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), LAUNCHER_MENUITEM_TYPE, new_launcher_item);
1039+ dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), INDICATOR_MENUITEM_TYPE, new_indicator_item);
1040
1041 return GTK_MENU(menu);
1042 }
1043
1044=== modified file 'src/messages-service.c'
1045--- src/messages-service.c 2009-09-03 19:13:45 +0000
1046+++ src/messages-service.c 2009-09-05 03:06:42 +0000
1047@@ -49,7 +49,7 @@
1048 static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data);
1049 static void im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data);
1050 static void resort_menu (DbusmenuMenuitem * menushell);
1051-static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data);
1052+static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data);
1053 static void check_eclipses (AppMenuItem * ai);
1054 static void remove_eclipses (AppMenuItem * ai);
1055 static gboolean build_launcher (gpointer data);
1056@@ -71,6 +71,8 @@
1057 struct _serverList_t {
1058 IndicateListenerServer * server;
1059 AppMenuItem * menuitem;
1060+ gboolean attention;
1061+ guint count;
1062 GList * imList;
1063 };
1064
1065@@ -112,6 +114,7 @@
1066 IndicateListenerIndicator * indicator;
1067 DbusmenuMenuitem * menuitem;
1068 gulong timechange_cb;
1069+ gulong attentionchange_cb;
1070 };
1071
1072 static gboolean
1073@@ -390,6 +393,56 @@
1074 * More code
1075 */
1076
1077+/* Goes through all the servers and sees if any of them
1078+ want attention. If they do, then well we'll give it
1079+ to them. If they don't, let's not bother the user
1080+ any, shall we? */
1081+static void
1082+check_attention (void)
1083+{
1084+ GList * pointer;
1085+ for (pointer = serverList; pointer != NULL; pointer = g_list_next(pointer)) {
1086+ serverList_t * slt = (serverList_t *)pointer->data;
1087+ if (slt->attention) {
1088+ message_service_dbus_set_attention(dbus_interface, TRUE);
1089+ return;
1090+ }
1091+ }
1092+ message_service_dbus_set_attention(dbus_interface, FALSE);
1093+ return;
1094+}
1095+
1096+/* This checks a server listing to see if it should
1097+ have attention. It can get attention through it's
1098+ count or by having an indicator that is requestion
1099+ attention. */
1100+static void
1101+server_attention (serverList_t * slt)
1102+{
1103+ /* Count, easy yes and out. */
1104+ if (slt->count > 0) {
1105+ slt->attention = TRUE;
1106+ return;
1107+ }
1108+
1109+ /* Check to see if any of the indicators want attention */
1110+ GList * pointer;
1111+ for (pointer = slt->imList; pointer != NULL; pointer = g_list_next(pointer)) {
1112+ imList_t * ilt = (imList_t *)pointer->data;
1113+ if (im_menu_item_get_attention(IM_MENU_ITEM(ilt->menuitem))) {
1114+ slt->attention = TRUE;
1115+ return;
1116+ }
1117+ }
1118+
1119+ /* Nope, no one */
1120+ slt->attention = FALSE;
1121+ return;
1122+}
1123+
1124+/* A new server has been created on the indicate bus.
1125+ We need to check to see if we like it. And build
1126+ structures for it if so. */
1127 static void
1128 server_added (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
1129 {
1130@@ -413,26 +466,34 @@
1131 return;
1132 }
1133
1134+ /* Build the Menu item */
1135 AppMenuItem * menuitem = app_menu_item_new(listener, server);
1136- g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), NULL);
1137- g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell);
1138
1139+ /* Build a possible server structure */
1140 serverList_t * sl_item = g_new0(serverList_t, 1);
1141 sl_item->server = server;
1142 sl_item->menuitem = menuitem;
1143 sl_item->imList = NULL;
1144+ sl_item->attention = FALSE;
1145+ sl_item->count = 0;
1146
1147 /* Incase we got an indicator first */
1148 GList * alreadythere = g_list_find_custom(serverList, sl_item, serverList_equal);
1149 if (alreadythere != NULL) {
1150+ /* Use the one we already had */
1151 g_free(sl_item);
1152 sl_item = (serverList_t *)alreadythere->data;
1153 sl_item->menuitem = menuitem;
1154 serverList = g_list_sort(serverList, serverList_sort);
1155 } else {
1156+ /* Insert the new one in the list */
1157 serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
1158 }
1159
1160+ /* Connect the signals up to the menu item */
1161+ g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), sl_item);
1162+ g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell);
1163+
1164 dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
1165 /* Should be prepend ^ */
1166
1167@@ -442,6 +503,10 @@
1168 return;
1169 }
1170
1171+/* The name of a server has changed, we probably
1172+ need to reorder the menu to keep it in alphabetical
1173+ order. This happens often after we read the destkop
1174+ file from disk. */
1175 static void
1176 server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data)
1177 {
1178@@ -451,52 +516,37 @@
1179 return;
1180 }
1181
1182+/* If the count on the server changes, we need to know
1183+ whether that should be grabbing attention or not. If
1184+ it is, we need to reevaluate whether the whole thing
1185+ should be grabbing attention or not. */
1186 static void
1187 server_count_changed (AppMenuItem * appitem, guint count, gpointer data)
1188 {
1189- static gboolean showing_new_icon = FALSE;
1190-
1191- /* Quick check for a common case */
1192- if (count != 0 && showing_new_icon) {
1193- return;
1194- }
1195-
1196- /* Odd that we'd get a signal in this case, but let's
1197- take it out of the mix too */
1198- if (count == 0 && !showing_new_icon) {
1199- return;
1200- }
1201-
1202- if (count != 0) {
1203- g_debug("Setting image to 'new'");
1204- showing_new_icon = TRUE;
1205+ serverList_t * slt = (serverList_t *)data;
1206+ slt->count = count;
1207+
1208+ if (count == 0 && slt->attention) {
1209+ /* Regen based on indicators if the count isn't going to cause it. */
1210+ server_attention(slt);
1211+ /* If we're dropping let's see if we're the last. */
1212+ if (!slt->attention) {
1213+ check_attention();
1214+ }
1215+ }
1216+
1217+ if (count != 0 && !slt->attention) {
1218+ slt->attention = TRUE;
1219+ /* Let's tell everyone about us! */
1220 message_service_dbus_set_attention(dbus_interface, TRUE);
1221- return;
1222- }
1223-
1224- /* Okay, now at this point the count is zero and it
1225- might result in a switching of the icon back to being
1226- the plain one. Let's check. */
1227-
1228- gboolean we_have_indicators = FALSE;
1229- GList * appitems = serverList;
1230- for (; appitems != NULL; appitems = appitems->next) {
1231- AppMenuItem * appitem = ((serverList_t *)appitems->data)->menuitem;
1232- if (app_menu_item_get_count(appitem) != 0) {
1233- we_have_indicators = TRUE;
1234- break;
1235- }
1236- }
1237-
1238- if (!we_have_indicators) {
1239- g_debug("Setting image to boring");
1240- showing_new_icon = FALSE;
1241- message_service_dbus_set_attention(dbus_interface, FALSE);
1242 }
1243
1244 return;
1245 }
1246
1247+/* Respond to the IM entrie's time changing
1248+ which results in it needing to resort the list
1249+ and rebuild the menu to match. */
1250 static void
1251 im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data)
1252 {
1253@@ -506,6 +556,26 @@
1254 return;
1255 }
1256
1257+/* The IM entrie's request for attention has changed
1258+ so we need to pass that up the stack. */
1259+static void
1260+im_attention_changed (ImMenuItem * imitem, gboolean requestit, gpointer data)
1261+{
1262+ serverList_t * sl = (serverList_t *)data;
1263+
1264+ if (requestit) {
1265+ sl->attention = TRUE;
1266+ message_service_dbus_set_attention(dbus_interface, TRUE);
1267+ } else {
1268+ server_attention(sl);
1269+ if (!sl->attention) {
1270+ check_attention();
1271+ }
1272+ }
1273+
1274+ return;
1275+}
1276+
1277 static void
1278 server_removed (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
1279 {
1280@@ -525,7 +595,7 @@
1281
1282 while (sltp->imList) {
1283 imList_t * imitem = (imList_t *)sltp->imList->data;
1284- indicator_removed(listener, server, imitem->indicator, "message", data);
1285+ indicator_removed(listener, server, imitem->indicator, data);
1286 }
1287
1288 serverList = g_list_remove(serverList, sltp);
1289@@ -536,10 +606,14 @@
1290 g_object_unref(G_OBJECT(sltp->menuitem));
1291 }
1292
1293+ if (sltp->attention) {
1294+ /* Check to see if this was the server causing the menu item to
1295+ be lit up. */
1296+ check_attention();
1297+ }
1298+
1299 g_free(sltp);
1300
1301- /* Simulate a server saying zero to recalculate icon */
1302- server_count_changed(NULL, 0, NULL);
1303 check_hidden();
1304
1305 return;
1306@@ -646,8 +720,11 @@
1307 return;
1308 }
1309
1310+/* Responding to a new indicator showing up on the bus. We
1311+ need to create a menuitem for it and start populating the
1312+ internal structures to track it. */
1313 static void
1314-subtype_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data)
1315+indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data)
1316 {
1317 DbusmenuMenuitem * menushell = DBUSMENU_MENUITEM(data);
1318 if (menushell == NULL) {
1319@@ -655,105 +732,93 @@
1320 return;
1321 }
1322
1323- if (property == NULL || g_strcmp0(property, "subtype")) {
1324- /* We should only ever get subtypes, but just in case */
1325- g_warning("Subtype callback got a property '%s'", property);
1326- return;
1327- }
1328-
1329- if (propertydata == NULL || propertydata[0] == '\0') {
1330- /* It's possible that this message didn't have a subtype. That's
1331- * okay, but we don't want to display those */
1332- g_debug("No subtype");
1333- return;
1334- }
1335-
1336- g_debug("Message subtype: %s", propertydata);
1337-
1338- if (!g_strcmp0(propertydata, "im") || !g_strcmp0(propertydata, "login")) {
1339- imList_t * listItem = g_new0(imList_t, 1);
1340- listItem->server = server;
1341- listItem->indicator = indicator;
1342-
1343- g_debug("Building IM Item");
1344- ImMenuItem * menuitem = im_menu_item_new(listener, server, indicator, !g_strcmp0(propertydata, "im"));
1345- g_object_ref(G_OBJECT(menuitem));
1346- listItem->menuitem = DBUSMENU_MENUITEM(menuitem);
1347-
1348- g_debug("Finding the server entry");
1349- serverList_t sl_item_local;
1350- serverList_t * sl_item = NULL;
1351- sl_item_local.server = server;
1352- GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal);
1353-
1354- if (serverentry == NULL) {
1355- /* This sucks, we got an indicator before the server. I guess
1356- that's the joy of being asynchronous */
1357- serverList_t * sl_item = g_new0(serverList_t, 1);
1358- sl_item->server = server;
1359- sl_item->menuitem = NULL;
1360- sl_item->imList = NULL;
1361-
1362- serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
1363- } else {
1364- sl_item = (serverList_t *)serverentry->data;
1365- }
1366-
1367- g_debug("Adding to IM List");
1368- sl_item->imList = g_list_insert_sorted(sl_item->imList, listItem, imList_sort);
1369- listItem->timechange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_TIME_CHANGED, G_CALLBACK(im_time_changed), sl_item);
1370-
1371- g_debug("Placing in Shell");
1372- menushell_location_t msl;
1373- msl.found = FALSE;
1374- msl.position = 0;
1375- msl.server = server;
1376-
1377- dbusmenu_menuitem_foreach(DBUSMENU_MENUITEM(menushell), menushell_foreach_cb, &msl);
1378- if (msl.found) {
1379- dbusmenu_menuitem_child_add_position(menushell, DBUSMENU_MENUITEM(menuitem), msl.position);
1380- } else {
1381- g_warning("Unable to find server menu item");
1382- dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
1383- }
1384- }
1385-
1386- return;
1387-}
1388-
1389-static void
1390-indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
1391-{
1392- if (type == NULL || g_strcmp0(type, "message")) {
1393- /* We only care about message type indicators
1394- all of the others can go to the bit bucket */
1395- g_debug("Ignoreing indicator of type '%s'", type);
1396- return;
1397- }
1398- g_debug("Got a message");
1399-
1400- indicate_listener_get_property(listener, server, indicator, "subtype", subtype_cb, data);
1401- return;
1402-}
1403-
1404-static void
1405-indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * type, gpointer data)
1406+ imList_t * listItem = g_new0(imList_t, 1);
1407+ listItem->server = server;
1408+ listItem->indicator = indicator;
1409+
1410+ /* Building the IM Menu Item which is a subclass
1411+ of DBus Menuitem */
1412+ ImMenuItem * menuitem = im_menu_item_new(listener, server, indicator);
1413+ g_object_ref(G_OBJECT(menuitem));
1414+ listItem->menuitem = DBUSMENU_MENUITEM(menuitem);
1415+
1416+ /* Looking for a server entry to attach this indicator
1417+ to. If we can't find one then we have to build one
1418+ and attach the indicator to it. */
1419+ serverList_t sl_item_local;
1420+ serverList_t * sl_item = NULL;
1421+ sl_item_local.server = server;
1422+ GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal);
1423+
1424+ if (serverentry == NULL) {
1425+ /* This sucks, we got an indicator before the server. I guess
1426+ that's the joy of being asynchronous */
1427+ serverList_t * sl_item = g_new0(serverList_t, 1);
1428+ sl_item->server = server;
1429+ sl_item->menuitem = NULL;
1430+ sl_item->imList = NULL;
1431+ sl_item->attention = FALSE;
1432+ sl_item->count = 0;
1433+
1434+ serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort);
1435+ } else {
1436+ sl_item = (serverList_t *)serverentry->data;
1437+ }
1438+
1439+ /* Added a this entry into the IM list */
1440+ sl_item->imList = g_list_insert_sorted(sl_item->imList, listItem, imList_sort);
1441+ listItem->timechange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_TIME_CHANGED, G_CALLBACK(im_time_changed), sl_item);
1442+ listItem->attentionchange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED, G_CALLBACK(im_attention_changed), sl_item);
1443+
1444+ /* Check the length of the list. If we've got more inidactors
1445+ than we allow. Well. Someone's gotta pay. Sorry. I didn't
1446+ want to do this, but you did it to yourself. */
1447+ if (g_list_length(sl_item->imList) > MAX_NUMBER_OF_INDICATORS) {
1448+ GList * indicatoritem;
1449+ gint count;
1450+ for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) {
1451+ imList_t * im = (imList_t *)indicatoritem->data;
1452+ im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS);
1453+ }
1454+ }
1455+
1456+ /* Placing the item into the shell. Look to see if
1457+ we can find our server and slip in there. Otherwise
1458+ we'll just append. */
1459+ menushell_location_t msl;
1460+ msl.found = FALSE;
1461+ msl.position = 0;
1462+ msl.server = server;
1463+
1464+ dbusmenu_menuitem_foreach(DBUSMENU_MENUITEM(menushell), menushell_foreach_cb, &msl);
1465+ if (msl.found) {
1466+ dbusmenu_menuitem_child_add_position(menushell, DBUSMENU_MENUITEM(menuitem), msl.position);
1467+ } else {
1468+ g_warning("Unable to find server menu item");
1469+ dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
1470+ }
1471+
1472+ return;
1473+}
1474+
1475+/* Process and indicator getting removed from the system. We
1476+ first need to ensure that it's one of ours and figure out
1477+ where we put it. When we find all that out we can go through
1478+ the process of removing the effect it had on the system. */
1479+static void
1480+indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data)
1481 {
1482 g_debug("Removing %s %d", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator));
1483- if (type == NULL || g_strcmp0(type, "message")) {
1484- /* We only care about message type indicators
1485- all of the others can go to the bit bucket */
1486- g_debug("Ignoreing indicator of type '%s'", type);
1487- return;
1488- }
1489
1490 gboolean removed = FALSE;
1491
1492+ /* Find the server that was related to this item */
1493 serverList_t sl_item_local;
1494 serverList_t * sl_item = NULL;
1495 sl_item_local.server = server;
1496 GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal);
1497 if (serverentry == NULL) {
1498+ /* We didn't care about that server */
1499 return;
1500 }
1501 sl_item = (serverList_t *)serverentry->data;
1502@@ -771,11 +836,41 @@
1503 menuitem = ilt->menuitem;
1504 }
1505
1506+ /* If we found a menu item and an imList_t item then
1507+ we can go ahead and remove it. Otherwise we can
1508+ skip this and exit. */
1509 if (!removed && menuitem != NULL) {
1510 sl_item->imList = g_list_remove(sl_item->imList, ilt);
1511 g_signal_handler_disconnect(menuitem, ilt->timechange_cb);
1512+ g_signal_handler_disconnect(menuitem, ilt->attentionchange_cb);
1513 g_free(ilt);
1514
1515+ if (im_menu_item_get_attention(IM_MENU_ITEM(menuitem)) && im_menu_item_shown(IM_MENU_ITEM(menuitem))) {
1516+ /* If the removed indicator menu item was asking for
1517+ attention we need to see if this server should still
1518+ be asking for attention. */
1519+ server_attention(sl_item);
1520+ /* If the server is no longer asking for attention then
1521+ we need to check if the whole system should be. */
1522+ if (!sl_item->attention) {
1523+ check_attention();
1524+ }
1525+ }
1526+
1527+ if (im_menu_item_shown(IM_MENU_ITEM(menuitem)) && g_list_length(sl_item->imList) >= MAX_NUMBER_OF_INDICATORS) {
1528+ /* In this case we need to show a different indicator
1529+ becasue a shown one has left. But we're going to be
1530+ easy and set all the values. */
1531+ GList * indicatoritem;
1532+ gint count;
1533+ for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) {
1534+ imList_t * im = (imList_t *)indicatoritem->data;
1535+ im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS);
1536+ }
1537+ }
1538+
1539+ /* Hide the item immediately, and then remove it
1540+ which might take a little longer. */
1541 dbusmenu_menuitem_property_set(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
1542 dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), menuitem);
1543 removed = TRUE;

Subscribers

People subscribed via source and target branches

to all changes: