aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/app-indicator.c218
-rw-r--r--src/app-indicator.h20
-rw-r--r--src/application-service-marshal.list1
-rw-r--r--src/notification-item.xml6
5 files changed, 244 insertions, 4 deletions
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 32f512f..b3fa3e5 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_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,
LAST_SIGNAL
};
@@ -104,7 +109,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. */
@@ -116,6 +123,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) \
@@ -136,6 +145,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);
@@ -284,6 +294,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 */
@@ -333,6 +378,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
@@ -368,6 +430,9 @@ app_indicator_init (AppIndicator *self)
priv->icon_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;
@@ -419,6 +484,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,
@@ -491,6 +561,16 @@ app_indicator_finalize (GObject *object)
g_free(priv->icon_path);
priv->icon_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;
@@ -563,6 +643,43 @@ app_indicator_set_property (GObject * object, guint prop_id, const GValue * valu
priv->icon_path = g_value_dup_string(value);
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;
@@ -620,6 +737,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;
@@ -628,6 +753,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. */
@@ -1134,6 +1292,31 @@ app_indicator_set_icon (AppIndicator *self, const gchar *icon_name)
return;
}
+/**
+ 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;
+}
+
static void
activate_menuitem (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
{
@@ -1661,3 +1844,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 e37abd4..586d2dc 100644
--- a/src/app-indicator.h
+++ b/src/app-indicator.h
@@ -92,6 +92,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.
@@ -99,6 +104,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"
/**
@@ -152,8 +158,8 @@ 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.
+ @new_label: Slot for #AppIndicator::new-label.
@app_indicator_reserved_1: Reserved for future use.
- @app_indicator_reserved_2: Reserved for future use.
The signals and external functions that make up the #AppIndicator
class object.
@@ -181,9 +187,14 @@ 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);
+
/* Reserved */
void (*app_indicator_reserved_1)(void);
- void (*app_indicator_reserved_2)(void);
};
/**
@@ -226,6 +237,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);
/* Get properties */
const gchar * app_indicator_get_id (AppIndicator *self);
@@ -234,6 +248,8 @@ AppIndicatorStatus app_indicator_get_status (AppIndicator *
const gchar * app_indicator_get_icon (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/notification-item.xml b/src/notification-item.xml
index a0141c3..b339e7b 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 -->
@@ -24,6 +26,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>