summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Piñeiro <apinheiro@igalia.com>2012-09-24 15:09:43 +0200
committerAlejandro Piñeiro <apinheiro@igalia.com>2013-03-05 19:47:45 +0100
commit78a3590fd67338b63651fcf935aeeee4254ef1e1 (patch)
tree7ba421934ee0f8d736ca50d8eeb121d0855bafcb
parenta622d34444decbb98f66314871ab028d8c2f3327 (diff)
downloadclutter-78a3590fd67338b63651fcf935aeeee4254ef1e1.tar.gz
a11y: cally-util: use password-char to fill a key_event if required
-rw-r--r--clutter/cally/cally-util.c69
1 files changed, 61 insertions, 8 deletions
diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c
index 0a81471f5..fdef2951d 100644
--- a/clutter/cally/cally-util.c
+++ b/clutter/cally/cally-util.c
@@ -50,6 +50,8 @@
#include "cally-root.h"
#include "cally-stage.h"
+#define DEFAULT_PASSWORD_CHAR '*'
+
/* atkutil.h */
static guint cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
@@ -77,8 +79,6 @@ static gboolean notify_hf (gpointer k
static void insert_hf (gpointer key,
gpointer value,
gpointer data);
-static AtkKeyEventStruct * atk_key_event_from_clutter_event_key (ClutterKeyEvent *event);
-
/* This is just a copy of the Gail one, a shared library or place to
define it could be a good idea. */
@@ -249,7 +249,8 @@ cally_util_simulate_snooper_remove (void)
}
static AtkKeyEventStruct *
-atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event)
+atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
+ gunichar password_char)
{
AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1);
gunichar key_unichar;
@@ -267,7 +268,10 @@ atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event)
return NULL;
}
- atk_event->state = clutter_event->modifier_state;
+ if (password_char)
+ atk_event->state = 0;
+ else
+ atk_event->state = clutter_event->modifier_state;
/* We emit the clutter keyval. This is not exactly the one expected
by AtkKeyEventStruct, as it expects a Gdk-like event, with the
@@ -275,7 +279,10 @@ atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event)
that on the AT application.
More information: Bug 1952 and bug 2072
*/
- atk_event->keyval = clutter_event->keyval;
+ if (password_char)
+ atk_event->keyval = clutter_unicode_to_keysym (password_char);
+ else
+ atk_event->keyval = clutter_event->keyval;
/* It is expected to store a key defining string here (ie "Space" in
case you press a space). Anyway, there are no function on clutter
@@ -286,7 +293,10 @@ atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event)
More information: Bug 1952 and 2072
*/
- key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
+ if (password_char)
+ key_unichar = password_char;
+ else
+ key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar))
{
@@ -302,7 +312,15 @@ atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event)
atk_event->length = 0;
- atk_event->keycode = clutter_event->hardware_keycode;
+ /* Computing the hardware keycode from the password-char is
+ difficult. But we are in a password situation. We are already a
+ unichar that it is not the original one. Providing a "almost
+ real" keycode is irrelevant */
+ if (password_char)
+ atk_event->keycode = 0;
+ else
+ atk_event->keycode = clutter_event->hardware_keycode;
+
atk_event->timestamp = clutter_event->time;
#ifdef CALLY_DEBUG
@@ -335,6 +353,37 @@ insert_hf (gpointer key, gpointer value, gpointer data)
g_hash_table_insert (new_table, key, value);
}
+
+/*
+ * 0 if the key of that event is visible, in other case the password
+ * char
+ */
+static gunichar
+check_key_visibility (ClutterEvent *event)
+{
+ ClutterKeyEvent *key_event = (ClutterKeyEvent *)event;
+ AtkObject *accessible = clutter_actor_get_accessible (key_event->source);
+
+ g_return_val_if_fail (accessible != NULL, 0);
+
+ if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT)
+ return 0;
+
+ /* If it is a clutter text, we use his password char. Note that
+ although at Clutter toolkit itself, only ClutterText exposes a
+ password role, nothing prevents on any derived toolkit (like st)
+ to create a new actor that can behave like a password entry. And
+ the key event will still be emitted here. Although in that case
+ we would lose any password char from the derived toolkit, it is
+ still better fill this with a default unichar that the original
+ one */
+
+ if (CLUTTER_IS_TEXT (key_event->source))
+ return clutter_text_get_password_char (CLUTTER_TEXT (key_event->source));
+ else
+ return DEFAULT_PASSWORD_CHAR;
+}
+
static gboolean
cally_key_snooper (ClutterActor *actor,
ClutterEvent *event,
@@ -342,6 +391,7 @@ cally_key_snooper (ClutterActor *actor,
{
AtkKeyEventStruct *key_event = NULL;
gint consumed = 0;
+ gunichar password_char = 0;
/* filter key events */
if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE))
@@ -349,12 +399,15 @@ cally_key_snooper (ClutterActor *actor,
return FALSE;
}
+ password_char = check_key_visibility (event);
+
if (key_listener_list)
{
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
- key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event);
+ key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event,
+ password_char);
/* func data is inside the hash table */
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event);
g_hash_table_destroy (new_hash);