Hi, With all the integration cally-clutter bug [1] patches uploaded, I started to review my old TODO list.
I have some doubts about the real use-case for ClutterClone and how it should be managed from the a11y POV. In the old times, it was just ClutterCloneTexture. So, from a a11y POV CallyCloneTexture was just another image, like ClutterTexture, and if it was a clone was irrevelant. So on cally-0.8, CallyCloneTexture expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more general. You can clone any object, including groups, and made things like have one text entry, and a clone with different properties in the same window (example attached), updated both at once. The question is if the idea is have a ClutterClone as a "first-class" citizen inside the stage hierarchy (full clone), or it is just supposed to be a mirror image of the original object. In the case of the a11y POV this would mean (using my test attached), that if the text changes on the source, the clone should emit as well the text-changing signals. As ClutterClone smartly just paint the same object with different parameters, this would mean that it should be the cally object the one that should replicate the source clutter hierarchy to do that, something that just sound crazy. Taking into account that: * ClutterClone doesn't re-emit mirrored signals from the source (AFAIS), I think that likely the answer would be "yes, it is just a mirrored image, not a real full clone". * You can't interact directly with the clone (ie: focus, and so on). * It basic usage (right now) is clone textures. * Any other solution could be overwhelming. I think that the final solution would be that ClutterClone from the a11y POV should still be managed as a image (with the proper properties, position, size, etc.). Any mistake/problem with my reasoning? BR [1] http://bugzilla.o-hand.com/show_bug.cgi?id=2069 PS: Sorry for the long mail. === API (apinhe...@igalia.com)
/* * Silly ClutterClone test by * Alejandro Piñeiro Iglesias <apinhe...@igalia.com> */ #include <clutter/clutter.h> #define WIDTH 800 #define HEIGHT 600 #define HEIGHT_STEP 100 #define NUM_ENTRIES 3 static void make_ui (ClutterActor *stage) { ClutterActor *editable = NULL; ClutterActor *rectangle = NULL; ClutterActor *label = NULL; ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff }; ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 }; ClutterGeometry editable_geom = {150, 50, 100, 75}; ClutterActor *full_entry = NULL; ClutterActor *cloned_entry = NULL; clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); clutter_actor_set_size (stage, WIDTH, HEIGHT); label = clutter_text_new_full ("Sans Bold 32px", "Entry", &color_label); clutter_actor_set_position (label, 0, 50); /* editable */ editable = clutter_text_new_full ("Sans Bold 32px", "ddd", &color_text); clutter_actor_set_position (editable, 150, 50); clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE); clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE); clutter_text_set_selection_color (CLUTTER_TEXT (editable), &color_sel); clutter_actor_grab_key_focus (editable); clutter_actor_set_reactive (editable, TRUE); /* rectangle: to create a entry "feeling" */ rectangle = clutter_rectangle_new_with_color (&color_rect); clutter_actor_set_geometry (rectangle, &editable_geom); full_entry = clutter_group_new (); clutter_actor_set_position (full_entry, 0, 50); clutter_actor_set_size (full_entry, 100, 75); clutter_group_add (CLUTTER_GROUP (full_entry), label); clutter_group_add (CLUTTER_GROUP (full_entry), editable); clutter_group_add (CLUTTER_GROUP (full_entry), rectangle); clutter_actor_show_all (full_entry); clutter_actor_set_scale (full_entry, 2, 1); clutter_group_add (CLUTTER_GROUP (stage), full_entry); /* Cloning! */ cloned_entry = clutter_clone_new (full_entry); clutter_actor_set_position (cloned_entry, 50, 200); clutter_actor_set_scale (cloned_entry, 1, 2); clutter_actor_show_all (cloned_entry); clutter_actor_set_reactive (cloned_entry, TRUE); clutter_group_add (CLUTTER_GROUP (stage), cloned_entry); } int main (int argc, char *argv[]) { ClutterActor *stage = NULL; g_set_application_name ("Clone Example"); clutter_init (&argc, &argv); stage = clutter_stage_get_default (); make_ui (stage); clutter_actor_show_all (stage); clutter_main (); return 0; }