[clutter] a11y: redoing focus stuff



commit cc126f55eb948a528211bc1649cd20bc7a7c0ed7
Author: Alejandro PiÃeiro <apinheiro igalia com>
Date:   Wed Feb 8 18:46:11 2012 +0100

    a11y: redoing focus stuff
    
    Removing atkcomponent, focus_tracker, etc. Emitting focus state change
    from the stage. Now things are more simple, and stop to use some
    of the soon-to-be-deprecated signals on ATK.

 clutter/cally/cally-actor.c |  114 ++----------------------------------------
 clutter/cally/cally-actor.h |   17 +++---
 clutter/cally/cally-stage.c |   47 ++++++++++++++++++
 3 files changed, 61 insertions(+), 117 deletions(-)
---
diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c
index ca4af30..8fd4705 100644
--- a/clutter/cally/cally-actor.c
+++ b/clutter/cally/cally-actor.c
@@ -43,7 +43,12 @@
  * clutter_stage_set_key_focus. So, we will use this approach: all actors are
  * focusable, and we get the currently focused using clutter_stage_get_key_focus
  * This affects focus related stateset and some atk_componenet focus methods (like
- * grab focus)
+ * grab focus).
+ *
+ * In the same way, we will manage the focus state change management
+ * on the cally-stage object. The reason is avoid missing a focus
+ * state change event if the object is focused just before the
+ * accessibility object being created.
  *
  * ####
  *
@@ -177,12 +182,6 @@ static void     cally_actor_get_extents              (AtkComponent *component,
                                                      AtkCoordType  coord_type);
 static gint     cally_actor_get_mdi_zorder           (AtkComponent *component);
 static gboolean cally_actor_grab_focus               (AtkComponent *component);
-static guint    cally_actor_add_focus_handler        (AtkComponent *component,
-                                                      AtkFocusHandler handler);
-static void     cally_actor_remove_focus_handler     (AtkComponent *component,
-                                                      guint handler_id);
-static void     cally_actor_focus_event              (AtkObject   *obj,
-                                                      gboolean    focus_in);
 
 /* AtkAction.h */
 static void                  cally_actor_action_interface_init  (AtkActionIface *iface);
@@ -210,10 +209,6 @@ static void cally_actor_notify_clutter          (GObject    *obj,
                                                 GParamSpec *pspec);
 static void cally_actor_real_notify_clutter     (GObject    *obj,
                                                  GParamSpec *pspec);
-static gboolean cally_actor_focus_clutter       (ClutterActor *actor,
-                                                 gpointer      data);
-static gboolean cally_actor_real_focus_clutter  (ClutterActor *actor,
-                                                 gpointer      data);
 
 G_DEFINE_TYPE_WITH_CODE (CallyActor,
                          cally_actor,
@@ -277,20 +272,10 @@ cally_actor_initialize (AtkObject *obj,
   priv = self->priv;
   actor = CLUTTER_ACTOR (data);
 
-  g_signal_connect_after (actor,
-                          "key-focus-in",
-                          G_CALLBACK (cally_actor_focus_clutter),
-                          GINT_TO_POINTER (TRUE));
-  g_signal_connect_after (actor,
-                          "key-focus-out",
-                          G_CALLBACK (cally_actor_focus_clutter),
-                          GINT_TO_POINTER (FALSE));
   g_signal_connect (actor,
                     "notify",
                     G_CALLBACK (cally_actor_notify_clutter),
                     NULL);
-  atk_component_add_focus_handler (ATK_COMPONENT (self),
-                                   cally_actor_focus_event);
 
   g_object_set_data (G_OBJECT (obj), "atk-component-layer",
                      GINT_TO_POINTER (ATK_LAYER_MDI));
@@ -324,7 +309,6 @@ cally_actor_class_init (CallyActorClass *klass)
   AtkObjectClass *class         = ATK_OBJECT_CLASS (klass);
   GObjectClass   *gobject_class = G_OBJECT_CLASS (klass);
 
-  klass->focus_clutter  = cally_actor_real_focus_clutter;
   klass->notify_clutter = cally_actor_real_notify_clutter;
   klass->add_actor      = cally_actor_real_add_actor;
   klass->remove_actor   = cally_actor_real_remove_actor;
@@ -728,8 +712,6 @@ cally_actor_component_interface_init (AtkComponentIface *iface)
 
   /* focus management */
   iface->grab_focus           = cally_actor_grab_focus;
-  iface->add_focus_handler    = cally_actor_add_focus_handler;
-  iface->remove_focus_handler = cally_actor_remove_focus_handler;
 }
 
 static void
@@ -814,46 +796,6 @@ cally_actor_grab_focus (AtkComponent    *component)
 }
 
 /*
- * These methods are basically taken from gail, as I don't see any
- * reason to modify it. It makes me wonder why it is really required
- * to be implemented in the toolkit
- */
-static guint
-cally_actor_add_focus_handler (AtkComponent *component,
-                               AtkFocusHandler handler)
-{
-  GSignalMatchType match_type;
-  gulong ret;
-  guint signal_id;
-
-  match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
-  signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
-
-  ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
-                               (gpointer) handler, NULL);
-  if (!ret)
-    {
-      return g_signal_connect_closure_by_id (component,
-                                             signal_id, 0,
-                                             g_cclosure_new (G_CALLBACK (handler), NULL,
-                                                             (GClosureNotify) NULL),
-                                             FALSE);
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-static void
-cally_actor_remove_focus_handler (AtkComponent *component,
-                                  guint handler_id)
-{
-  g_signal_handler_disconnect (component, handler_id);
-}
-
-
-/*
  *
  * This gets the top level origin, it is, the position of the stage in
  * the global screen. You can see it as the absolute display position
@@ -1091,42 +1033,6 @@ cally_actor_action_get_keybinding (AtkAction *action,
 /* Misc functions */
 
 /*
- * This function is a signal handler for key_focus_in and
- * key_focus_out signal which gets emitted on a ClutterActor
- */
-static gboolean
-cally_actor_focus_clutter (ClutterActor *actor,
-                           gpointer      data)
-{
-  CallyActor      *cally_actor = NULL;
-  CallyActorClass *klass       = NULL;
-
-  cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (actor));
-  klass = CALLY_ACTOR_GET_CLASS (cally_actor);
-  if (klass->focus_clutter)
-    return klass->focus_clutter (actor, data);
-  else
-    return FALSE;
-}
-
-static gboolean
-cally_actor_real_focus_clutter (ClutterActor *actor,
-                                gpointer      data)
-{
-  CallyActor *cally_actor = NULL;
-  gboolean return_val = FALSE;
-  gboolean in = FALSE;
-
-  in = GPOINTER_TO_INT (data);
-  cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (actor));
-
-  g_signal_emit_by_name (cally_actor, "focus_event", in, &return_val);
-  atk_focus_tracker_notify (ATK_OBJECT (cally_actor));
-
-  return FALSE;
-}
-
-/*
  * This function is a signal handler for notify signal which gets emitted
  * when a property changes value on the ClutterActor associated with the object.
  *
@@ -1185,14 +1091,6 @@ cally_actor_real_notify_clutter (GObject    *obj,
 }
 
 static void
-cally_actor_focus_event (AtkObject   *obj,
-                         gboolean    focus_in)
-{
-  atk_object_notify_state_change (obj, ATK_STATE_FOCUSED, focus_in);
-}
-
-
-static void
 _cally_actor_clean_action_list (CallyActor *cally_actor)
 {
   CallyActorPrivate *priv = NULL;
diff --git a/clutter/cally/cally-actor.h b/clutter/cally/cally-actor.h
index f4a58b2..415054e 100644
--- a/clutter/cally/cally-actor.h
+++ b/clutter/cally/cally-actor.h
@@ -89,12 +89,15 @@ struct _CallyActor
 /**
  * CallyActorClass:
  * @notify_clutter: Signal handler for notify signal on Clutter actor
- * @focus_clutter: Signal handler for key-focus-in and key-focus-out signal on Clutter actor
- * @add_actor: Signal handler for actor-added signal on ClutterContainer interface
- * @remove_actor: Signal handler for actor-added signal on ClutterContainer interface
+ * @focus_clutter: Signal handler for key-focus-in and key-focus-out
+ *   signal on Clutter actor. This virtual functions is deprecated.
+ * @add_actor: Signal handler for actor-added signal on
+ *   ClutterContainer interface
+ * @remove_actor: Signal handler for actor-added signal on
+ *   ClutterContainer interface
  *
- * The <structname>CallyActorClass</structname> structure contains only
- * private data
+ * The <structname>CallyActorClass</structname> structure contains
+ * only private data
  *
  * Since: 1.4
  */
@@ -104,13 +107,9 @@ struct _CallyActorClass
   AtkGObjectAccessibleClass parent_class;
 
   /*< public >*/
-  /* Signal handler for notify signal on Clutter Actor */
   void     (*notify_clutter) (GObject    *object,
                               GParamSpec *pspec);
 
-  /*
-   * Signal handler for key_focus_in and key_focus_out on Clutter Actor
-   */
   gboolean (*focus_clutter)  (ClutterActor *actor,
                               gpointer      data);
 
diff --git a/clutter/cally/cally-stage.c b/clutter/cally/cally-stage.c
index 6c2c3b5..aff7dc0 100644
--- a/clutter/cally/cally-stage.c
+++ b/clutter/cally/cally-stage.c
@@ -67,6 +67,9 @@ G_DEFINE_TYPE_WITH_CODE (CallyStage,
 
 struct _CallyStagePrivate
 {
+  /* NULL means that the stage will receive the focus */
+  ClutterActor *key_focus;
+
   gboolean active;
 };
 
@@ -122,6 +125,48 @@ cally_stage_new (ClutterActor *actor)
 }
 
 static void
+cally_stage_notify_key_focus_cb (ClutterStage *stage,
+                                 GParamSpec   *pspec,
+                                 CallyStage   *self)
+{
+  ClutterActor *key_focus = NULL;
+  AtkObject *new = NULL;
+
+  if (self->priv->active == FALSE)
+    return;
+
+  key_focus = clutter_stage_get_key_focus (stage);
+
+  if (key_focus != self->priv->key_focus)
+    {
+      AtkObject *old = NULL;
+
+      if (self->priv->key_focus != NULL)
+        old = clutter_actor_get_accessible (self->priv->key_focus);
+      else
+        old = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
+
+      atk_object_notify_state_change (old,
+                                      ATK_STATE_FOCUSED,
+                                      FALSE);
+    }
+
+  /* we keep notifying the focus gain without checking previous
+   * key-focus to avoid some missing events due timing
+   */
+  self->priv->key_focus = key_focus;
+
+  if (key_focus != NULL)
+    new = clutter_actor_get_accessible (key_focus);
+  else
+    new = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
+
+  atk_object_notify_state_change (new,
+                                  ATK_STATE_FOCUSED,
+                                  TRUE);
+}
+
+static void
 cally_stage_real_initialize (AtkObject *obj,
                              gpointer  data)
 {
@@ -135,6 +180,8 @@ cally_stage_real_initialize (AtkObject *obj,
 
   g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj);
   g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj);
+  g_signal_connect (stage, "notify::key-focus",
+                    G_CALLBACK (cally_stage_notify_key_focus_cb), obj);
 
   obj->role = ATK_ROLE_CANVAS;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]