aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-08-05 17:06:59 -0500
committerTed Gould <ted@gould.cx>2010-08-05 17:06:59 -0500
commit649c799e5edc8d22c4b55af75c88aebf0c6d61f3 (patch)
treed30e3faf06f835f07b360b83615f44c73b414efb
parent9291697e3e6d4270a7f6200c0dc3d85743feb6d2 (diff)
parentd377c945f1dcc36710313fdfa7e79b725fa8d42e (diff)
downloadayatana-indicator-application-649c799e5edc8d22c4b55af75c88aebf0c6d61f3.tar.gz
ayatana-indicator-application-649c799e5edc8d22c4b55af75c88aebf0c6d61f3.tar.bz2
ayatana-indicator-application-649c799e5edc8d22c4b55af75c88aebf0c6d61f3.zip
Adding label support
-rw-r--r--.bzrignore2
-rw-r--r--docs/reference/libappindicator-sections.txt4
-rw-r--r--example/simple-client.c41
-rw-r--r--src/Makefile.am3
-rw-r--r--src/app-indicator.c218
-rw-r--r--src/app-indicator.h19
-rw-r--r--src/application-service-marshal.list1
-rw-r--r--src/dbus-properties-client.h139
-rw-r--r--src/notification-item.xml6
-rw-r--r--tests/test-libappindicator.c133
10 files changed, 423 insertions, 143 deletions
diff --git a/.bzrignore b/.bzrignore
index cbf5964..94155ae 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -111,3 +111,5 @@ src/notification-approver-client.h
src/notification-approver-server.h
tests/test-approver
tests/test-approver-tester
+bindings/mono/policy.0.0.appindicator-sharp.config
+bindings/mono/policy.0.0.appindicator-sharp.dll
diff --git a/docs/reference/libappindicator-sections.txt b/docs/reference/libappindicator-sections.txt
index e0436ed..a342d99 100644
--- a/docs/reference/libappindicator-sections.txt
+++ b/docs/reference/libappindicator-sections.txt
@@ -9,6 +9,7 @@ APP_INDICATOR_GET_CLASS
APP_INDICATOR_SIGNAL_NEW_ICON
APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON
APP_INDICATOR_SIGNAL_NEW_STATUS
+APP_INDICATOR_SIGNAL_NEW_LABEL
APP_INDICATOR_SIGNAL_NEW_ICON_THEME_PATH
APP_INDICATOR_SIGNAL_CONNECTION_CHANGED
AppIndicatorCategory
@@ -25,6 +26,7 @@ app_indicator_set_attention_icon
app_indicator_set_menu
app_indicator_set_icon
app_indicator_set_icon_theme_path
+app_indicator_set_label
app_indicator_get_id
app_indicator_get_category
app_indicator_get_status
@@ -32,5 +34,7 @@ app_indicator_get_icon
app_indicator_get_icon_theme_path
app_indicator_get_attention_icon
app_indicator_get_menu
+app_indicator_get_label
+app_indicator_get_label_guide
</SECTION>
diff --git a/example/simple-client.c b/example/simple-client.c
index fbcaaaa..f2fac6f 100644
--- a/example/simple-client.c
+++ b/example/simple-client.c
@@ -26,6 +26,21 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
GMainLoop * mainloop = NULL;
static gboolean active = TRUE;
+static gboolean can_haz_label = TRUE;
+
+static void
+label_toggle_cb (GtkWidget * widget, gpointer data)
+{
+ can_haz_label = !can_haz_label;
+
+ if (can_haz_label) {
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Hide label");
+ } else {
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Show label");
+ }
+
+ return;
+}
static void
activate_clicked_cb (GtkWidget *widget, gpointer data)
@@ -97,6 +112,22 @@ append_submenu (GtkWidget *item)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
}
+guint percentage = 0;
+
+static gboolean
+percent_change (gpointer user_data)
+{
+ percentage = (percentage + 1) % 100;
+ if (can_haz_label) {
+ gchar * percentstr = g_strdup_printf("%d%%", percentage + 1);
+ app_indicator_set_label (APP_INDICATOR(user_data), percentstr, "100%");
+ g_free(percentstr);
+ } else {
+ app_indicator_set_label (APP_INDICATOR(user_data), NULL, NULL);
+ }
+ return TRUE;
+}
+
int
main (int argc, char ** argv)
{
@@ -114,6 +145,9 @@ main (int argc, char ** argv)
app_indicator_set_status (ci, APP_INDICATOR_STATUS_ACTIVE);
app_indicator_set_attention_icon(ci, "indicator-messages-new");
+ app_indicator_set_label (ci, "1%", "100%");
+
+ g_timeout_add_seconds(1, percent_change, ci);
menu = gtk_menu_new ();
GtkWidget *item = gtk_check_menu_item_new_with_label ("1");
@@ -151,6 +185,13 @@ main (int argc, char ** argv)
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show(item);
+ item = gtk_menu_item_new_with_label ("Show label");
+ label_toggle_cb(item, ci);
+ g_signal_connect (item, "activate",
+ G_CALLBACK (label_toggle_cb), ci);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show(item);
+
app_indicator_set_menu (ci, GTK_MENU (menu));
mainloop = g_main_loop_new(NULL, FALSE);
diff --git a/src/Makefile.am b/src/Makefile.am
index 68be1c0..b704b5e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -94,7 +94,8 @@ BUILT_SOURCES += \
libappindicator_la_SOURCES = \
$(libappindicator_headers) \
app-indicator-enum-types.c \
- app-indicator.c
+ app-indicator.c \
+ application-service-marshal.c
libappindicator_la_LDFLAGS = \
-version-info 0:0:0 \
diff --git a/src/app-indicator.c b/src/app-indicator.c
index fdfcc23..22b9c03 100644
--- a/src/app-indicator.c
+++ b/src/app-indicator.c
@@ -37,6 +37,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "app-indicator.h"
#include "app-indicator-enum-types.h"
+#include "application-service-marshal.h"
#include "notification-item-server.h"
#include "notification-watcher-client.h"
@@ -72,6 +73,9 @@ struct _AppIndicatorPrivate {
gchar *icon_theme_path;
DbusmenuServer *menuservice;
GtkWidget *menu;
+ gchar * label;
+ gchar * label_guide;
+ guint label_change_idle;
GtkStatusIcon * status_icon;
gint fallback_timer;
@@ -87,6 +91,7 @@ enum {
NEW_ICON,
NEW_ATTENTION_ICON,
NEW_STATUS,
+ NEW_LABEL,
CONNECTION_CHANGED,
NEW_ICON_THEME_PATH,
LAST_SIGNAL
@@ -105,7 +110,9 @@ enum {
PROP_ATTENTION_ICON_NAME,
PROP_ICON_THEME_PATH,
PROP_MENU,
- PROP_CONNECTED
+ PROP_CONNECTED,
+ PROP_LABEL,
+ PROP_LABEL_GUIDE
};
/* The strings so that they can be slowly looked up. */
@@ -117,6 +124,8 @@ enum {
#define PROP_ICON_THEME_PATH_S "icon-theme-path"
#define PROP_MENU_S "menu"
#define PROP_CONNECTED_S "connected"
+#define PROP_LABEL_S "label"
+#define PROP_LABEL_GUIDE_S "label-guide"
/* Private macro, shhhh! */
#define APP_INDICATOR_GET_PRIVATE(o) \
@@ -137,6 +146,7 @@ static void app_indicator_finalize (GObject *object);
static void app_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
static void app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
/* Other stuff */
+static void signal_label_change (AppIndicator * self);
static void check_connect (AppIndicator * self);
static void register_service_cb (DBusGProxy * proxy, GError * error, gpointer data);
static void start_fallback_timer (AppIndicator * self, gboolean disable_timeout);
@@ -285,6 +295,41 @@ app_indicator_class_init (AppIndicatorClass *klass)
"Pretty simple, true if we have a reasonable expectation of being displayed through this object. You should hide your TrayIcon if so.",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ /**
+ AppIndicator:label:
+
+ A label that can be shown next to the string in the application
+ indicator. The label will not be shown unless there is an icon
+ as well. The label is useful for numerical and other frequently
+ updated information. In general, it shouldn't be shown unless a
+ user requests it as it can take up a significant amount of space
+ on the user's panel. This may not be shown in all visualizations.
+ */
+ g_object_class_install_property(object_class,
+ PROP_LABEL,
+ g_param_spec_string (PROP_LABEL_S,
+ "A label next to the icon",
+ "A label to provide dynamic information.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ AppIndicator:label-guide:
+
+ An optional string to provide guidance to the panel on how big
+ the #AppIndicator:label string could get. If this is set correctly
+ then the panel should never 'jiggle' as the string adjusts through
+ out the range of options. For instance, if you were providing a
+ percentage like "54% thrust" in #AppIndicator:label you'd want to
+ set this string to "100% thrust" to ensure space when Scotty can
+ get you enough power.
+ */
+ g_object_class_install_property(object_class,
+ PROP_LABEL_GUIDE,
+ g_param_spec_string (PROP_LABEL_GUIDE_S,
+ "A string to size the space available for the label.",
+ "To ensure that the label does not cause the panel to 'jiggle' this string should provide information on how much space it could take.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* Signals */
@@ -334,6 +379,23 @@ app_indicator_class_init (AppIndicatorClass *klass)
G_TYPE_STRING);
/**
+ AppIndicator::new-label:
+ @arg0: The #AppIndicator object
+ @arg1: The string for the label
+ @arg1: The string for the guide
+
+ Emitted when either #AppIndicator:label or #AppIndicator:label-guide are
+ changed.
+ */
+ signals[NEW_LABEL] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_LABEL,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AppIndicatorClass, new_label),
+ NULL, NULL,
+ _application_service_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+
+ /**
AppIndicator::connection-changed:
@arg0: The #AppIndicator object
@arg1: Whether we're connected or not
@@ -384,6 +446,9 @@ app_indicator_init (AppIndicator *self)
priv->icon_theme_path = NULL;
priv->menu = NULL;
priv->menuservice = NULL;
+ priv->label = NULL;
+ priv->label_guide = NULL;
+ priv->label_change_idle = 0;
priv->watcher_proxy = NULL;
priv->connection = NULL;
@@ -435,6 +500,11 @@ app_indicator_dispose (GObject *object)
priv->fallback_timer = 0;
}
+ if (priv->label_change_idle != 0) {
+ g_source_remove(priv->label_change_idle);
+ priv->label_change_idle = 0;
+ }
+
if (priv->menu != NULL) {
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->menu),
client_menu_changed,
@@ -507,6 +577,16 @@ app_indicator_finalize (GObject *object)
g_free(priv->icon_theme_path);
priv->icon_theme_path = NULL;
}
+
+ if (priv->label != NULL) {
+ g_free(priv->label);
+ priv->label = NULL;
+ }
+
+ if (priv->label_guide != NULL) {
+ g_free(priv->label_guide);
+ priv->label_guide = NULL;
+ }
G_OBJECT_CLASS (app_indicator_parent_class)->finalize (object);
return;
@@ -578,6 +658,43 @@ app_indicator_set_property (GObject * object, guint prop_id, const GValue * valu
check_connect (self);
break;
+ case PROP_LABEL: {
+ gchar * oldlabel = priv->label;
+ priv->label = g_value_dup_string(value);
+
+ if (g_strcmp0(oldlabel, priv->label) != 0) {
+ signal_label_change(APP_INDICATOR(object));
+ }
+
+ if (priv->label != NULL && priv->label[0] == '\0') {
+ g_free(priv->label);
+ priv->label = NULL;
+ }
+
+ if (oldlabel != NULL) {
+ g_free(oldlabel);
+ }
+ break;
+ }
+ case PROP_LABEL_GUIDE: {
+ gchar * oldguide = priv->label_guide;
+ priv->label_guide = g_value_dup_string(value);
+
+ if (g_strcmp0(oldguide, priv->label_guide) != 0) {
+ signal_label_change(APP_INDICATOR(object));
+ }
+
+ if (priv->label_guide != NULL && priv->label_guide[0] == '\0') {
+ g_free(priv->label_guide);
+ priv->label_guide = NULL;
+ }
+
+ if (oldguide != NULL) {
+ g_free(oldguide);
+ }
+ break;
+ }
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -635,6 +752,14 @@ app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GPa
g_value_set_boolean (value, priv->watcher_proxy != NULL ? TRUE : FALSE);
break;
+ case PROP_LABEL:
+ g_value_set_string (value, priv->label);
+ break;
+
+ case PROP_LABEL_GUIDE:
+ g_value_set_string (value, priv->label_guide);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -643,6 +768,39 @@ app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GPa
return;
}
+/* Sends the label changed signal and resets the source ID */
+static gboolean
+signal_label_change_idle (gpointer user_data)
+{
+ AppIndicator * self = (AppIndicator *)user_data;
+ AppIndicatorPrivate *priv = self->priv;
+
+ g_signal_emit(G_OBJECT(self), signals[NEW_LABEL], 0,
+ priv->label != NULL ? priv->label : "",
+ priv->label_guide != NULL ? priv->label_guide : "",
+ TRUE);
+
+ priv->label_change_idle = 0;
+
+ return FALSE;
+}
+
+/* Sets up an idle function to send the label changed signal
+ so that we don't send it too many times. */
+static void
+signal_label_change (AppIndicator * self)
+{
+ AppIndicatorPrivate *priv = self->priv;
+
+ /* don't set it twice */
+ if (priv->label_change_idle != 0) {
+ return;
+ }
+
+ priv->label_change_idle = g_idle_add(signal_label_change_idle, self);
+ return;
+}
+
/* This function is used to see if we have enough information to
connect to things. If we do, and we're not connected, it
connects for us. */
@@ -1150,6 +1308,31 @@ app_indicator_set_icon (AppIndicator *self, const gchar *icon_name)
}
/**
+ app_indicator_set_label:
+ @self: The #AppIndicator object to use
+ @label: The label to show next to the icon.
+ @guide: A guide to size the label correctly.
+
+ This is a wrapper function for the #AppIndicator:label and
+ #AppIndicator:guide properties. This function can take #NULL
+ as either @label or @guide and will clear the entries.
+*/
+void
+app_indicator_set_label (AppIndicator *self, const gchar * label, const gchar * guide)
+{
+ g_return_if_fail (IS_APP_INDICATOR (self));
+ /* Note: The label can be NULL, it's okay */
+ /* Note: The guide can be NULL, it's okay */
+
+ g_object_set(G_OBJECT(self),
+ PROP_LABEL_S, label == NULL ? "" : label,
+ PROP_LABEL_GUIDE_S, guide == NULL ? "" : guide,
+ NULL);
+
+ return;
+}
+
+/**
app_indicator_set_icon_theme_path:
@self: The #AppIndicator object to use
@icon_theme_path: The icon theme path to set.
@@ -1717,3 +1900,36 @@ app_indicator_get_menu (AppIndicator *self)
return GTK_MENU(priv->menu);
}
+
+/**
+ app_indicator_get_label:
+ @self: The #AppIndicator object to use
+
+ Wrapper function for property #AppIndicator:label.
+
+ Return value: The current label.
+*/
+const gchar *
+app_indicator_get_label (AppIndicator *self)
+{
+ g_return_val_if_fail (IS_APP_INDICATOR (self), NULL);
+
+ return self->priv->label;
+}
+
+/**
+ app_indicator_get_label_guide:
+ @self: The #AppIndicator object to use
+
+ Wrapper function for property #AppIndicator:label-guide.
+
+ Return value: The current label guide.
+*/
+const gchar *
+app_indicator_get_label_guide (AppIndicator *self)
+{
+ g_return_val_if_fail (IS_APP_INDICATOR (self), NULL);
+
+ return self->priv->label_guide;
+}
+
diff --git a/src/app-indicator.h b/src/app-indicator.h
index b17f023..8320a2f 100644
--- a/src/app-indicator.h
+++ b/src/app-indicator.h
@@ -93,6 +93,11 @@ G_BEGIN_DECLS
String identifier for the #AppIndicator::new-status signal.
*/
/**
+ APP_INDICATOR_SIGNAL_NEW_LABEL:
+
+ String identifier for the #AppIndicator::new-label signal.
+*/
+/**
APP_INDICATOR_SIGNAL_CONNECTION_CHANGED:
String identifier for the #AppIndicator::connection-changed signal.
@@ -105,6 +110,7 @@ G_BEGIN_DECLS
#define APP_INDICATOR_SIGNAL_NEW_ICON "new-icon"
#define APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON "new-attention-icon"
#define APP_INDICATOR_SIGNAL_NEW_STATUS "new-status"
+#define APP_INDICATOR_SIGNAL_NEW_LABEL "new-label"
#define APP_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed"
#define APP_INDICATOR_SIGNAL_NEW_ICON_THEME_PATH "new-icon-theme-path"
@@ -160,7 +166,7 @@ typedef struct _AppIndicatorPrivate AppIndicatorPrivate;
there is no Application Indicator area available.
@unfallback: The function that gets called if an Application
Indicator area appears after the fallback has been created.
- @app_indicator_reserved_2: Reserved for future use.
+ @new_label: Slot for #AppIndicator::new-label.
The signals and external functions that make up the #AppIndicator
class object.
@@ -188,12 +194,16 @@ struct _AppIndicatorClass {
void (*unfallback) (AppIndicator * indicator,
GtkStatusIcon * status_icon);
+ /* Another DBus Signal */
+ void (* new_label) (AppIndicator *indicator,
+ const gchar *label,
+ const gchar *guide,
+ gpointer user_data);
void (* new_icon_theme_path) (AppIndicator *indicator,
const gchar *icon_theme_path,
gpointer user_data);
/* Reserved */
- void (*app_indicator_reserved_2)(void);
};
/**
@@ -236,6 +246,9 @@ void app_indicator_set_menu (AppIndicator
GtkMenu *menu);
void app_indicator_set_icon (AppIndicator *self,
const gchar *icon_name);
+void app_indicator_set_label (AppIndicator *self,
+ const gchar *label,
+ const gchar *guide);
void app_indicator_set_icon_theme_path(AppIndicator *self,
const gchar *icon_theme_path);
@@ -247,6 +260,8 @@ const gchar * app_indicator_get_icon (AppIndicator *
const gchar * app_indicator_get_icon_theme_path(AppIndicator *self);
const gchar * app_indicator_get_attention_icon (AppIndicator *self);
GtkMenu * app_indicator_get_menu (AppIndicator *self);
+const gchar * app_indicator_get_label (AppIndicator *self);
+const gchar * app_indicator_get_label_guide (AppIndicator *self);
G_END_DECLS
diff --git a/src/application-service-marshal.list b/src/application-service-marshal.list
index 4ac8398..b49ff41 100644
--- a/src/application-service-marshal.list
+++ b/src/application-service-marshal.list
@@ -18,3 +18,4 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
VOID: STRING, INT, STRING, STRING, STRING
VOID: INT, STRING
+VOID: STRING, STRING
diff --git a/src/dbus-properties-client.h b/src/dbus-properties-client.h
deleted file mode 100644
index 6f08e78..0000000
--- a/src/dbus-properties-client.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Generated by dbus-binding-tool; do not edit! */
-
-#include <glib.h>
-#include <dbus/dbus-glib.h>
-
-G_BEGIN_DECLS
-
-#ifndef _DBUS_GLIB_ASYNC_DATA_FREE
-#define _DBUS_GLIB_ASYNC_DATA_FREE
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-void
-_dbus_glib_async_data_free (gpointer stuff)
-{
- g_slice_free (DBusGAsyncData, stuff);
-}
-#endif
-
-#ifndef DBUS_GLIB_CLIENT_WRAPPERS_org_freedesktop_DBus_Properties
-#define DBUS_GLIB_CLIENT_WRAPPERS_org_freedesktop_DBus_Properties
-
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-gboolean
-org_freedesktop_DBus_Properties_get (DBusGProxy *proxy, const char * IN_Interface_Name, const char * IN_Property_Name, GValue* OUT_Value, GError **error)
-
-{
- return dbus_g_proxy_call (proxy, "Get", error, G_TYPE_STRING, IN_Interface_Name, G_TYPE_STRING, IN_Property_Name, G_TYPE_INVALID, G_TYPE_VALUE, OUT_Value, G_TYPE_INVALID);
-}
-
-typedef void (*org_freedesktop_DBus_Properties_get_reply) (DBusGProxy *proxy, GValue OUT_Value, GError *error, gpointer userdata);
-
-static void
-org_freedesktop_DBus_Properties_get_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
-{
- DBusGAsyncData *data = (DBusGAsyncData*) user_data;
- GError *error = NULL;
- GValue OUT_Value = { 0, };
- dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_VALUE, &OUT_Value, G_TYPE_INVALID);
- (*(org_freedesktop_DBus_Properties_get_reply)data->cb) (proxy, OUT_Value, error, data->userdata);
- return;
-}
-
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-DBusGProxyCall*
-org_freedesktop_DBus_Properties_get_async (DBusGProxy *proxy, const char * IN_Interface_Name, const char * IN_Property_Name, org_freedesktop_DBus_Properties_get_reply callback, gpointer userdata)
-
-{
- DBusGAsyncData *stuff;
- stuff = g_slice_new (DBusGAsyncData);
- stuff->cb = G_CALLBACK (callback);
- stuff->userdata = userdata;
- return dbus_g_proxy_begin_call (proxy, "Get", org_freedesktop_DBus_Properties_get_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_Interface_Name, G_TYPE_STRING, IN_Property_Name, G_TYPE_INVALID);
-}
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-gboolean
-org_freedesktop_DBus_Properties_set (DBusGProxy *proxy, const char * IN_Interface_Name, const char * IN_Property_Name, const GValue* IN_Value, GError **error)
-
-{
- return dbus_g_proxy_call (proxy, "Set", error, G_TYPE_STRING, IN_Interface_Name, G_TYPE_STRING, IN_Property_Name, G_TYPE_VALUE, IN_Value, G_TYPE_INVALID, G_TYPE_INVALID);
-}
-
-typedef void (*org_freedesktop_DBus_Properties_set_reply) (DBusGProxy *proxy, GError *error, gpointer userdata);
-
-static void
-org_freedesktop_DBus_Properties_set_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
-{
- DBusGAsyncData *data = (DBusGAsyncData*) user_data;
- GError *error = NULL;
- dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
- (*(org_freedesktop_DBus_Properties_set_reply)data->cb) (proxy, error, data->userdata);
- return;
-}
-
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-DBusGProxyCall*
-org_freedesktop_DBus_Properties_set_async (DBusGProxy *proxy, const char * IN_Interface_Name, const char * IN_Property_Name, const GValue* IN_Value, org_freedesktop_DBus_Properties_set_reply callback, gpointer userdata)
-
-{
- DBusGAsyncData *stuff;
- stuff = g_slice_new (DBusGAsyncData);
- stuff->cb = G_CALLBACK (callback);
- stuff->userdata = userdata;
- return dbus_g_proxy_begin_call (proxy, "Set", org_freedesktop_DBus_Properties_set_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_Interface_Name, G_TYPE_STRING, IN_Property_Name, G_TYPE_VALUE, IN_Value, G_TYPE_INVALID);
-}
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-gboolean
-org_freedesktop_DBus_Properties_get_all (DBusGProxy *proxy, const char * IN_Interface_Name, GHashTable** OUT_Properties, GError **error)
-
-{
- return dbus_g_proxy_call (proxy, "GetAll", error, G_TYPE_STRING, IN_Interface_Name, G_TYPE_INVALID, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), OUT_Properties, G_TYPE_INVALID);
-}
-
-typedef void (*org_freedesktop_DBus_Properties_get_all_reply) (DBusGProxy *proxy, GHashTable *OUT_Properties, GError *error, gpointer userdata);
-
-static void
-org_freedesktop_DBus_Properties_get_all_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
-{
- DBusGAsyncData *data = (DBusGAsyncData*) user_data;
- GError *error = NULL;
- GHashTable* OUT_Properties;
- dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &OUT_Properties, G_TYPE_INVALID);
- (*(org_freedesktop_DBus_Properties_get_all_reply)data->cb) (proxy, OUT_Properties, error, data->userdata);
- return;
-}
-
-static
-#ifdef G_HAVE_INLINE
-inline
-#endif
-DBusGProxyCall*
-org_freedesktop_DBus_Properties_get_all_async (DBusGProxy *proxy, const char * IN_Interface_Name, org_freedesktop_DBus_Properties_get_all_reply callback, gpointer userdata)
-
-{
- DBusGAsyncData *stuff;
- stuff = g_slice_new (DBusGAsyncData);
- stuff->cb = G_CALLBACK (callback);
- stuff->userdata = userdata;
- return dbus_g_proxy_begin_call (proxy, "GetAll", org_freedesktop_DBus_Properties_get_all_async_callback, stuff, _dbus_glib_async_data_free, G_TYPE_STRING, IN_Interface_Name, G_TYPE_INVALID);
-}
-#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_freedesktop_DBus_Properties */
-
-G_END_DECLS
diff --git a/src/notification-item.xml b/src/notification-item.xml
index dc755c9..01261b5 100644
--- a/src/notification-item.xml
+++ b/src/notification-item.xml
@@ -12,6 +12,8 @@
to find the icons specified above. -->
<property name="IconThemePath" type="s" access="read" />
<property name="Menu" type="o" access="read" />
+ <property name="Label" type="s" access="read" />
+ <property name="LabelGuide" type="s" access="read" />
<!-- Methods -->
<!-- None currently -->
@@ -27,6 +29,10 @@
<signal name="NewStatus">
<arg type="s" name="status" direction="out" />
</signal>
+ <signal name="NewLabel">
+ <arg type="s" name="label" direction="out" />
+ <arg type="s" name="guide" direction="out" />
+ </signal>
</interface>
</node>
diff --git a/tests/test-libappindicator.c b/tests/test-libappindicator.c
index 86879b3..8d12ac5 100644
--- a/tests/test-libappindicator.c
+++ b/tests/test-libappindicator.c
@@ -163,12 +163,145 @@ test_libappindicator_init (void)
}
void
+test_libappindicator_set_label (void)
+{
+ AppIndicator * ci = app_indicator_new ("my-id",
+ "my-name",
+ APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
+
+ g_assert(ci != NULL);
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ /* First check all the clearing modes, this is important as
+ we're going to use them later, we need them to work. */
+ app_indicator_set_label(ci, NULL, NULL);
+
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, "", NULL);
+
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, NULL, "");
+
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, "", "");
+
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, "label", "");
+
+ g_assert(g_strcmp0(app_indicator_get_label(ci), "label") == 0);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, NULL, NULL);
+
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ app_indicator_set_label(ci, "label", "guide");
+
+ g_assert(g_strcmp0(app_indicator_get_label(ci), "label") == 0);
+ g_assert(g_strcmp0(app_indicator_get_label_guide(ci), "guide") == 0);
+
+ app_indicator_set_label(ci, "label2", "guide");
+
+ g_assert(g_strcmp0(app_indicator_get_label(ci), "label2") == 0);
+ g_assert(g_strcmp0(app_indicator_get_label_guide(ci), "guide") == 0);
+
+ app_indicator_set_label(ci, "trick-label", "trick-guide");
+
+ g_assert(g_strcmp0(app_indicator_get_label(ci), "trick-label") == 0);
+ g_assert(g_strcmp0(app_indicator_get_label_guide(ci), "trick-guide") == 0);
+
+ g_object_unref(G_OBJECT(ci));
+ return;
+}
+
+void
+label_signals_cb (AppIndicator * appindicator, gchar * label, gchar * guide, gpointer user_data)
+{
+ gint * label_signals_count = (gint *)user_data;
+ (*label_signals_count)++;
+ return;
+}
+
+void
+label_signals_check (void)
+{
+ while (g_main_context_pending(NULL)) {
+ g_main_context_iteration(NULL, TRUE);
+ }
+
+ return;
+}
+
+void
+test_libappindicator_label_signals (void)
+{
+ gint label_signals_count = 0;
+ AppIndicator * ci = app_indicator_new ("my-id",
+ "my-name",
+ APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
+
+ g_assert(ci != NULL);
+ g_assert(app_indicator_get_label(ci) == NULL);
+ g_assert(app_indicator_get_label_guide(ci) == NULL);
+
+ g_signal_connect(G_OBJECT(ci), APP_INDICATOR_SIGNAL_NEW_LABEL, G_CALLBACK(label_signals_cb), &label_signals_count);
+
+ /* Shouldn't be a signal as it should be stuck in idle */
+ app_indicator_set_label(ci, "label", "guide");
+ g_assert(label_signals_count == 0);
+
+ /* Should show up after idle processing */
+ label_signals_check();
+ g_assert(label_signals_count == 1);
+
+ /* Shouldn't signal with no change */
+ label_signals_count = 0;
+ app_indicator_set_label(ci, "label", "guide");
+ label_signals_check();
+ g_assert(label_signals_count == 0);
+
+ /* Change one, we should get one signal */
+ app_indicator_set_label(ci, "label2", "guide");
+ label_signals_check();
+ g_assert(label_signals_count == 1);
+
+ /* Change several times, one signal */
+ label_signals_count = 0;
+ app_indicator_set_label(ci, "label1", "guide0");
+ app_indicator_set_label(ci, "label1", "guide1");
+ app_indicator_set_label(ci, "label2", "guide2");
+ app_indicator_set_label(ci, "label3", "guide3");
+ label_signals_check();
+ g_assert(label_signals_count == 1);
+
+ /* Clear should signal too */
+ label_signals_count = 0;
+ app_indicator_set_label(ci, NULL, NULL);
+ label_signals_check();
+ g_assert(label_signals_count == 1);
+
+ return;
+}
+
+void
test_libappindicator_props_suite (void)
{
g_test_add_func ("/indicator-application/libappindicator/init", test_libappindicator_init);
g_test_add_func ("/indicator-application/libappindicator/init_props", test_libappindicator_init_with_props);
g_test_add_func ("/indicator-application/libappindicator/init_set_props", test_libappindicator_init_set_props);
g_test_add_func ("/indicator-application/libappindicator/prop_signals", test_libappindicator_prop_signals);
+ g_test_add_func ("/indicator-application/libappindicator/set_label", test_libappindicator_set_label);
+ g_test_add_func ("/indicator-application/libappindicator/label_signals", test_libappindicator_label_signals);
return;
}