aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app-indicator.c161
-rw-r--r--src/app-indicator.h13
-rw-r--r--src/notification-item.xml5
3 files changed, 178 insertions, 1 deletions
diff --git a/src/app-indicator.c b/src/app-indicator.c
index 7bee341..de9dd39 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_name;
guint label_change_idle;
+ guint accessible_name_change_idle;
GtkStatusIcon * status_icon;
gint fallback_timer;
@@ -104,6 +106,7 @@ enum {
CONNECTION_CHANGED,
NEW_ICON_THEME_PATH,
SCROLL_EVENT,
+ NEW_ACCESSIBLE_NAME,
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_NAME
};
/* 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_NAME_S "accessible-name"
/* 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_name_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-name:
+
+ 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_NAME,
+ g_param_spec_string (PROP_ACCESSIBLE_NAME_S,
+ "A string that describes the indicator in text form.",
+ "This string shoudl 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-name:
+ @arg0: The #AppIndicator object
+ @arg1: The string for the accessible name
+
+ Emitted when #AppIndicator:accessible_name changes.
+ */
+ signals[NEW_ACCESSIBLE_NAME] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_ACCESSIBLE_NAME,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AppIndicatorClass, new_accessible_name),
+ NULL, NULL,
+ _application_service_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
/**
AppIndicator::connection-changed:
@@ -546,6 +583,7 @@ app_indicator_init (AppIndicator *self)
priv->label = NULL;
priv->label_guide = NULL;
priv->label_change_idle = 0;
+ priv->accessible_name_change_idle = 0;
priv->watcher_proxy = NULL;
priv->connection = NULL;
@@ -609,6 +647,11 @@ app_indicator_dispose (GObject *object)
priv->label_change_idle = 0;
}
+ if (priv->accessible_name_change_idle != 0) {
+ g_source_remove(priv->accessible_name_change_idle);
+ priv->accessible_name_change_idle = 0;
+ }
+
if (priv->menu != NULL) {
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->menu),
client_menu_changed,
@@ -686,6 +729,11 @@ app_indicator_finalize (GObject *object)
priv->label_guide = NULL;
}
+ if (priv->accessible_name != NULL) {
+ g_free(priv->accessible_name);
+ priv->accessible_name = NULL;
+ }
+
if (priv->path != NULL) {
g_free(priv->path);
priv->path = NULL;
@@ -797,6 +845,24 @@ app_indicator_set_property (GObject * object, guint prop_id, const GValue * valu
}
break;
}
+ case PROP_ACCESSIBLE_NAME: {
+ gchar * olda11yname = priv->accessible_name;
+ priv->accessible_name = g_value_dup_string(value);
+
+ if (g_strcmp0(olda11yname, priv->accessible_name) != 0) {
+ signal_accessible_name_change(APP_INDICATOR(object));
+ }
+
+ if (priv->accessible_name != NULL && priv->accessible_name[0] == '\0') {
+ g_free(priv->accessible_name);
+ priv->accessible_name = NULL;
+ }
+
+ if (olda11yname != NULL) {
+ g_free(olda11yname);
+ }
+ break;
+ }
case PROP_ORDERING_INDEX:
priv->ordering_index = g_value_get_uint(value);
break;
@@ -875,6 +941,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_NAME:
+ g_value_set_string (value, priv->accessible_name);
+ break;
+
case PROP_ORDERING_INDEX:
g_value_set_uint(value, priv->ordering_index);
break;
@@ -997,6 +1067,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, "AccessibleName") == 0) {
+ return g_variant_new_string(priv->accessible_name ? priv->accessible_name : "");
}
*error = g_error_new(0, 0, "Unknown property: %s", property);
@@ -1053,6 +1125,55 @@ signal_label_change (AppIndicator * self)
return;
}
+/* Sends the accessible name changed signal and resets the source ID */
+static gboolean
+signal_accessible_name_change_idle (gpointer user_data)
+{
+ AppIndicator * self = (AppIndicator *)user_data;
+ AppIndicatorPrivate *priv = self->priv;
+
+ gchar * accessible_name = priv->accessible_name != NULL ? priv->accessible_name : "";
+
+ g_signal_emit(G_OBJECT(self), signals[NEW_ACCESSIBLE_NAME], 0,
+ accessible_name, 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,
+ "NewAccessibleName",
+ g_variant_new("(s)", accessible_name),
+ &error);
+
+ if (error != NULL) {
+ g_warning("Unable to send signal for NewIcon: %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ priv->accessible_name_change_idle = 0;
+
+ return FALSE;
+}
+
+/* Sets up an idle function to send the accessible name changed
+ signal so that we don't send it too many times. */
+static void
+signal_accessible_name_change (AppIndicator * self)
+{
+ AppIndicatorPrivate *priv = self->priv;
+
+ /* don't set it twice */
+ if (priv->accessible_name_change_idle != 0) {
+ return;
+ }
+
+ priv->accessible_name_change_idle = g_idle_add(signal_accessible_name_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. */
@@ -1719,6 +1840,28 @@ app_indicator_set_label (AppIndicator *self, const gchar * label, const gchar *
}
/**
+ app_indicator_set_accessible_name:
+ @self: The #AppIndicator object to use
+ @accessible_name: The accessible name used by assistive technologies.
+
+ This is a wrapper function for the #AppIndicator:accessible_name
+ property. This function can take #NULL as @accessible_name and
+ will clear the entry.
+*/
+void
+app_indicator_set_accessible_name (AppIndicator *self, const gchar * accessible_name)
+{
+ g_return_if_fail (IS_APP_INDICATOR (self));
+ /* Note: The accessible name can be NULL, it's okay */
+
+ g_object_set(G_OBJECT(self),
+ PROP_ACCESSIBLE_NAME_S, accessible_name == NULL ? "" : accessible_name,
+ NULL);
+
+ return;
+}
+
+/**
app_indicator_set_icon_theme_path:
@self: The #AppIndicator object to use
@icon_theme_path: The icon theme path to set.
@@ -2013,6 +2156,22 @@ app_indicator_get_label_guide (AppIndicator *self)
}
/**
+ app_indicator_get_accessible_name:
+ @self: The #AppIndicator object to use
+
+ Wrapper function for property #AppIndicator:accessible_name.
+
+ Return value: The current accessible name.
+*/
+const gchar *
+app_indicator_get_accessible_name (AppIndicator *self)
+{
+ g_return_val_if_fail (IS_APP_INDICATOR (self), NULL);
+
+ return self->priv->accessible_name;
+}
+
+/**
app_indicator_get_ordering_index:
@self: The #AppIndicator object to use
diff --git a/src/app-indicator.h b/src/app-indicator.h
index abd6699..0d4473d 100644
--- a/src/app-indicator.h
+++ b/src/app-indicator.h
@@ -112,6 +112,11 @@ G_BEGIN_DECLS
String identifier for the #AppIndicator::scroll-event signal.
*/
+/**
+ APP_INDICATOR_SIGNAL_NEW_ACCESSIBLE_NAME:
+
+ String identifier for the #AppIndicator::new-accessible-name signal.
+*/
#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"
@@ -119,6 +124,7 @@ G_BEGIN_DECLS
#define APP_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed"
#define APP_INDICATOR_SIGNAL_NEW_ICON_THEME_PATH "new-icon-theme-path"
#define APP_INDICATOR_SIGNAL_SCROLL_EVENT "scroll-event"
+#define APP_INDICATOR_SIGNAL_NEW_ACCESSIBLE_NAME "new-accessible-name"
/**
AppIndicatorCategory:
@@ -168,6 +174,7 @@ typedef struct _AppIndicatorPrivate AppIndicatorPrivate;
@new_status: Slot for #AppIndicator::new-status.
@new_icon_theme_path: Slot for #AppIndicator::new-icon-theme-path
@new_label: Slot for #AppIndicator::new-label.
+ @new_accessible_name: Slot for #AppIndicator::new-accessible-name.
@connection_changed: Slot for #AppIndicator::connection-changed.
@scroll-event: Slot for #AppIndicator::scroll-event
@app_indicator_reserved_ats: Reserved for future use.
@@ -204,6 +211,9 @@ struct _AppIndicatorClass {
const gchar *label,
const gchar *guide,
gpointer user_data);
+ void (* new_accessible_name) (AppIndicator *indicator,
+ const gchar *accessible_name);
+
/* Local Signals */
void (* connection_changed) (AppIndicator * indicator,
@@ -274,6 +284,8 @@ void app_indicator_set_icon (AppIndicator
void app_indicator_set_label (AppIndicator *self,
const gchar *label,
const gchar *guide);
+void app_indicator_set_accessible_name(AppIndicator *self,
+ const gchar *accessible_name);
void app_indicator_set_icon_theme_path(AppIndicator *self,
const gchar *icon_theme_path);
void app_indicator_set_ordering_index (AppIndicator *self,
@@ -289,6 +301,7 @@ const gchar * app_indicator_get_attention_icon (AppIndicator *
GtkMenu * app_indicator_get_menu (AppIndicator *self);
const gchar * app_indicator_get_label (AppIndicator *self);
const gchar * app_indicator_get_label_guide (AppIndicator *self);
+const gchar * app_indicator_get_accessible_name(AppIndicator *self);
guint32 app_indicator_get_ordering_index (AppIndicator *self);
/* Helpers */
diff --git a/src/notification-item.xml b/src/notification-item.xml
index 127eb3a..737ecb3 100644
--- a/src/notification-item.xml
+++ b/src/notification-item.xml
@@ -15,6 +15,7 @@
<property name="XAyatanaLabel" type="s" access="read" />
<property name="XAyatanaLabelGuide" type="s" access="read" />
<property name="XAyatanaOrderingIndex" type="u" access="read" />
+ <property name="AccessibleName" type="s" access="read" />
<!-- Methods -->
<method name="Scroll">
@@ -37,5 +38,9 @@
<arg type="s" name="label" direction="out" />
<arg type="s" name="guide" direction="out" />
</signal>
+ <signal name="AccessibleName">
+ <arg type="s" name="accessible_name" direction="out" />
+ </signal>
+
</interface>
</node>