aboutsummaryrefslogtreecommitdiff
path: root/src/app-indicator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app-indicator.c')
-rw-r--r--src/app-indicator.c161
1 files changed, 160 insertions, 1 deletions
diff --git a/src/app-indicator.c b/src/app-indicator.c
index f4e9173..c3da8ed 100644
--- a/src/app-indicator.c
+++ b/src/app-indicator.c
@@ -80,7 +80,9 @@ struct _AppIndicatorPrivate {
guint32 ordering_index;
gchar * label;
gchar * label_guide;
+ gchar * accessible_desc;
guint label_change_idle;
+ guint accessible_desc_change_idle;
GtkStatusIcon * status_icon;
gint fallback_timer;
@@ -104,6 +106,7 @@ enum {
CONNECTION_CHANGED,
NEW_ICON_THEME_PATH,
SCROLL_EVENT,
+ NEW_ACCESSIBLE_DESC,
LAST_SIGNAL
};
@@ -123,7 +126,8 @@ enum {
PROP_LABEL,
PROP_LABEL_GUIDE,
PROP_ORDERING_INDEX,
- PROP_DBUS_MENU_SERVER
+ PROP_DBUS_MENU_SERVER,
+ PROP_ACCESSIBLE_DESC
};
/* The strings so that they can be slowly looked up. */
@@ -138,6 +142,7 @@ enum {
#define PROP_LABEL_GUIDE_S "label-guide"
#define PROP_ORDERING_INDEX_S "ordering-index"
#define PROP_DBUS_MENU_SERVER_S "dbus-menu-server"
+#define PROP_ACCESSIBLE_DESC_S "accessible-desc"
/* Private macro, shhhh! */
#define APP_INDICATOR_GET_PRIVATE(o) \
@@ -165,6 +170,7 @@ static void app_indicator_set_property (GObject * object, guint prop_id, const G
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 signal_accessible_desc_change (AppIndicator * self);
static void check_connect (AppIndicator * self);
static void register_service_cb (GObject * obj, GAsyncResult * res, gpointer user_data);
static void start_fallback_timer (AppIndicator * self, gboolean disable_timeout);
@@ -346,6 +352,22 @@ app_indicator_class_init (AppIndicatorClass *klass)
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
+ AppIndicator:accessible-desc:
+
+ A string that describes the indicator in text form. This string is
+ used to identify the indicator to users of assistive technologies, such
+ as screen readers. If the indicator has a label, then duplicating the
+ contents of the label is fine, if the label alone conveys enough
+ information about the state of the indicator to the user.
+ */
+ g_object_class_install_property(object_class,
+ PROP_ACCESSIBLE_DESC,
+ g_param_spec_string (PROP_ACCESSIBLE_DESC_S,
+ "A string that describes the indicator in text form.",
+ "This string should convey a description of the indicator's current status, for users who use assistive technologies.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
AppIndicator:ordering-index:
The ordering index is an odd parameter, and if you think you don't need
@@ -442,6 +464,21 @@ app_indicator_class_init (AppIndicatorClass *klass)
_application_service_marshal_VOID__STRING_STRING,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+ /**
+ AppIndicator::new-accessible-desc:
+ @arg0: The #AppIndicator object
+ @arg1: The string for the accessible description
+
+ Emitted when #AppIndicator:accessible_desc changes.
+ */
+ signals[NEW_ACCESSIBLE_DESC] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_ACCESSIBLE_DESC,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AppIndicatorClass, new_accessible_desc),
+ NULL, NULL,
+ _application_service_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
/**
AppIndicator::connection-changed:
@@ -548,6 +585,7 @@ app_indicator_init (AppIndicator *self)
priv->label = NULL;
priv->label_guide = NULL;
priv->label_change_idle = 0;
+ priv->accessible_desc_change_idle = 0;
priv->watcher_proxy = NULL;
priv->connection = NULL;
@@ -611,6 +649,11 @@ app_indicator_dispose (GObject *object)
priv->label_change_idle = 0;
}
+ if (priv->accessible_desc_change_idle != 0) {
+ g_source_remove(priv->accessible_desc_change_idle);
+ priv->accessible_desc_change_idle = 0;
+ }
+
if (priv->menu != NULL) {
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->menu),
client_menu_changed,
@@ -688,6 +731,11 @@ app_indicator_finalize (GObject *object)
priv->label_guide = NULL;
}
+ if (priv->accessible_desc != NULL) {
+ g_free(priv->accessible_desc);
+ priv->accessible_desc = NULL;
+ }
+
if (priv->path != NULL) {
g_free(priv->path);
priv->path = NULL;
@@ -799,6 +847,24 @@ app_indicator_set_property (GObject * object, guint prop_id, const GValue * valu
}
break;
}
+ case PROP_ACCESSIBLE_DESC: {
+ gchar * olda11ydesc = priv->accessible_desc;
+ priv->accessible_desc = g_value_dup_string(value);
+
+ if (g_strcmp0(olda11ydesc, priv->accessible_desc) != 0) {
+ signal_accessible_desc_change(APP_INDICATOR(object));
+ }
+
+ if (priv->accessible_desc != NULL && priv->accessible_desc[0] == '\0') {
+ g_free(priv->accessible_desc);
+ priv->accessible_desc = NULL;
+ }
+
+ if (olda11ydesc != NULL) {
+ g_free(olda11ydesc);
+ }
+ break;
+ }
case PROP_ORDERING_INDEX:
priv->ordering_index = g_value_get_uint(value);
break;
@@ -877,6 +943,10 @@ app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GPa
g_value_set_string (value, priv->label_guide);
break;
+ case PROP_ACCESSIBLE_DESC:
+ g_value_set_string (value, priv->accessible_desc);
+ break;
+
case PROP_ORDERING_INDEX:
g_value_set_uint(value, priv->ordering_index);
break;
@@ -999,6 +1069,8 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar *
return g_variant_new_string(priv->label_guide ? priv->label_guide : "");
} else if (g_strcmp0(property, "XAyatanaOrderingIndex") == 0) {
return g_variant_new_uint32(priv->ordering_index);
+ } else if (g_strcmp0(property, "AccessibleDesc") == 0) {
+ return g_variant_new_string(priv->accessible_desc ? priv->accessible_desc : "");
}
*error = g_error_new(0, 0, "Unknown property: %s", property);
@@ -1055,6 +1127,55 @@ signal_label_change (AppIndicator * self)
return;
}
+/* Sends the accessible description changed signal and resets the source ID */
+static gboolean
+signal_accessible_desc_change_idle (gpointer user_data)
+{
+ AppIndicator * self = (AppIndicator *)user_data;
+ AppIndicatorPrivate *priv = self->priv;
+
+ gchar * accessible_desc = priv->accessible_desc != NULL ? priv->accessible_desc : "";
+
+ g_signal_emit(G_OBJECT(self), signals[NEW_ACCESSIBLE_DESC], 0,
+ accessible_desc, TRUE);
+ if (priv->dbus_registration != 0 && priv->connection != NULL) {
+ GError * error = NULL;
+
+ g_dbus_connection_emit_signal(priv->connection,
+ NULL,
+ priv->path,
+ NOTIFICATION_ITEM_DBUS_IFACE,
+ "NewAccessibleDesc",
+ g_variant_new("(s)", accessible_desc),
+ &error);
+
+ if (error != NULL) {
+ g_warning("Unable to send signal for NewAccessibleDesc: %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ priv->accessible_desc_change_idle = 0;
+
+ return FALSE;
+}
+
+/* Sets up an idle function to send the accessible description
+ changed signal so that we don't send it too many times. */
+static void
+signal_accessible_desc_change (AppIndicator * self)
+{
+ AppIndicatorPrivate *priv = self->priv;
+
+ /* don't set it twice */
+ if (priv->accessible_desc_change_idle != 0) {
+ return;
+ }
+
+ priv->accessible_desc_change_idle = g_idle_add(signal_accessible_desc_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. */
@@ -1721,6 +1842,28 @@ app_indicator_set_label (AppIndicator *self, const gchar * label, const gchar *
}
/**
+ app_indicator_set_accessible_desc:
+ @self: The #AppIndicator object to use
+ @accessible_desc: The accessible description used by assistive technologies.
+
+ This is a wrapper function for the #AppIndicator:accessible_desc
+ property. This function can take #NULL as @accessible_desc and
+ will clear the entry.
+*/
+void
+app_indicator_set_accessible_desc (AppIndicator *self, const gchar * accessible_desc)
+{
+ g_return_if_fail (IS_APP_INDICATOR (self));
+ /* Note: The accessible description can be NULL, it's okay */
+
+ g_object_set(G_OBJECT(self),
+ PROP_ACCESSIBLE_DESC_S, accessible_desc == NULL ? "" : accessible_desc,
+ NULL);
+
+ return;
+}
+
+/**
app_indicator_set_icon_theme_path:
@self: The #AppIndicator object to use
@icon_theme_path: The icon theme path to set.
@@ -2015,6 +2158,22 @@ app_indicator_get_label_guide (AppIndicator *self)
}
/**
+ app_indicator_get_accessible_desc:
+ @self: The #AppIndicator object to use
+
+ Wrapper function for property #AppIndicator:accessible_desc.
+
+ Return value: The current accessible description.
+*/
+const gchar *
+app_indicator_get_accessible_desc (AppIndicator *self)
+{
+ g_return_val_if_fail (IS_APP_INDICATOR (self), NULL);
+
+ return self->priv->accessible_desc;
+}
+
+/**
app_indicator_get_ordering_index:
@self: The #AppIndicator object to use