[TV] Apply live region politeness attribute when handling value-changed event 56/292756/1 accepted/tizen/7.0/unified/20230515.132828 accepted/tizen/7.0/unified/20230515.152732
authorLukasz Oleksak <l.oleksak@samsung.com>
Wed, 10 May 2023 10:18:43 +0000 (12:18 +0200)
committerLukasz Oleksak <l.oleksak@samsung.com>
Fri, 12 May 2023 08:49:59 +0000 (10:49 +0200)
This patch:

* extends applicability of "container-live" ATSPI attribute
  (mapped from WAI-ARIA "aria-live") to case of handling value-change event

* changes default value of live region politeness attribute from "assertive"
  to "off" for text-changed and value-changed events emitted from
  not currently focused UI element

Change-Id: Iff20c8f9855cd19c5b00e59c1319253a15a1971d

include/utils.h
src/app_tracker.c
src/screen_reader_spi.c
src/utils.c

index 1287fb38013ba28b266b0162e1248204d189b72c..645e7f7df1b3e4a9437e4bbf33c8be3271949811 100644 (file)
@@ -137,6 +137,7 @@ void utils_a11y_bus_connection_set(Eldbus_Connection *conn);
 Eldbus_Connection *utils_a11y_bus_connection_get(void);
 
 Eina_Bool object_has_modal_role(AtspiRole role);
+Eina_Bool object_has_focused_state(AtspiAccessible *obj);
 Eina_Bool object_has_defunct_state(AtspiAccessible *obj);
 Eina_Bool object_has_highlighted_state(AtspiAccessible *obj);
 
@@ -144,6 +145,8 @@ int get_percent_value(double value, double lower, double upper);
 
 Eina_Bool is_same_str (const char *s1, const char *s2);
 
+Live_Region_Politeness try_parse_politeness(GHashTable *attrs);
+
 static inline void ESAL(Eina_Strbuf *buf, const char *txt)
 {
        // Note: This was previously defined as a macro:
index ac7b08e7d62f1387e8ad88292b2216b7127a1ec8..9b3bb377a5d5f82c79133f637421ac0491df0c74 100644 (file)
@@ -529,16 +529,10 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
 
                        GHashTable *attrs = atspi_accessible_get_attributes(event->source, NULL);
 
-                       Live_Region_Politeness mode = ACCESSIBLE_LIVE_REGION_ASSERTIVE;
-                       if (attrs) {
-                               char *val = g_hash_table_lookup(attrs, "container-live");
-                               DEBUG("got attributes, containter-live is '%s'", val);
-                               if (val) {
-                                       if (g_strcmp0(val, "polite") == 0) mode = ACCESSIBLE_LIVE_REGION_POLITE;
-                                       else if (g_strcmp0(val, "off") == 0) mode = ACCESSIBLE_LIVE_REGION_OFF;
-                               }
+                       Live_Region_Politeness mode = try_parse_politeness(attrs);
+
+                       if (attrs)
                                g_hash_table_destroy(attrs);
-                       }
 
                        DEBUG("speaking mode is %d", mode);
                        if (mode != ACCESSIBLE_LIVE_REGION_OFF)
index 5f5acf125ff0f297dfe144b55ce1dbdb1c003439..7a395cf66572d32b1c0a4fa6f828e6291148ffa0 100644 (file)
@@ -306,33 +306,15 @@ void spi_event_get_text_to_read(
        } else if (!g_strcmp0(event->type, TEXT_INSERT_SIG)) {
                DEBUG("Set ignore_next_caret_move event to true");
                spi->ignore_next_caret_move = EINA_TRUE;
-               Live_Region_Politeness mode = ACCESSIBLE_LIVE_REGION_ASSERTIVE;
-               if (attrs) {
-                       char *val = g_hash_table_lookup(attrs, "container-live");
-                       DEBUG("got attributes, containter-live is '%s'", val);
-                       if (val) {
-                               if (g_strcmp0(val, "polite") == 0) mode = ACCESSIBLE_LIVE_REGION_POLITE;
-                               else if (g_strcmp0(val, "off") == 0) mode = ACCESSIBLE_LIVE_REGION_OFF;
-                       }
-               }
-               DEBUG("speaking mode is %d", mode);
-               if (mode != ACCESSIBLE_LIVE_REGION_OFF) {
+               Live_Region_Politeness mode = try_parse_politeness(attrs);
+               if (object_has_focused_state(event->source) || mode != ACCESSIBLE_LIVE_REGION_OFF) {
                        *text_to_read = spi_on_text_insert_get_text(spi, event);
                        if (cancel)
                                *cancel = mode == ACCESSIBLE_LIVE_REGION_ASSERTIVE ? 1 : 0;
                }
        } else if (!g_strcmp0(event->type, TEXT_DELETE_SIG)) {
-               int mode = ACCESSIBLE_LIVE_REGION_ASSERTIVE;
-               if (attrs) {
-                       char *val = g_hash_table_lookup(attrs, "container-live");
-                       DEBUG("got attributes, containter-live is '%s'", val);
-                       if (val) {
-                               if (g_strcmp0(val, "polite") == 0) mode = ACCESSIBLE_LIVE_REGION_POLITE;
-                               else if (g_strcmp0(val, "off") == 0) mode = ACCESSIBLE_LIVE_REGION_OFF;
-                       }
-               }
-               DEBUG("speaking mode is %d", mode);
-               if (mode != ACCESSIBLE_LIVE_REGION_OFF) {
+               Live_Region_Politeness mode = try_parse_politeness(attrs);
+               if (object_has_focused_state(event->source) || mode != ACCESSIBLE_LIVE_REGION_OFF) {
                        *text_to_read = spi_on_text_delete_get_text(spi, event);
                        if (cancel)
                                *cancel = mode == ACCESSIBLE_LIVE_REGION_ASSERTIVE ? 1 : 0;
@@ -342,14 +324,17 @@ void spi_event_get_text_to_read(
                        spi->ignore_next_caret_move = EINA_TRUE;
                }
        } else if (!g_strcmp0(event->type, VALUE_CHANGED_SIG)) {
-               *text_to_read = spi_on_value_changed_get_text(spi, event);
-
+               Live_Region_Politeness mode = try_parse_politeness(attrs);
+               if (object_has_focused_state(event->source) || mode != ACCESSIBLE_LIVE_REGION_OFF) {
+                       *text_to_read = spi_on_value_changed_get_text(spi, event);
+                       if (cancel)
+                               *cancel = mode == ACCESSIBLE_LIVE_REGION_ASSERTIVE ? 1 : 0;
+               }
        } else if (!g_strcmp0(event->type, STATE_CHECKED_SIG)) {
                if (event->detail1)
                        *text_to_read = g_strdup(_("IDS_ACCS_TBOPT_CHECKED_TTS"));
                else
                        *text_to_read = g_strdup(_("IDS_ACCS_TBOPT_NOT_CHECKED_TTS"));
-
        } else {
                ERROR("Unknown event type");
        }
index 2dfddb3167987bd6f3cbb0359d4c0e0d669a507d..0702ec03deebe730c2269c98f876ad27e36ec9c0 100644 (file)
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <atspi/atspi.h>
 #include <glib.h>
 #include <string.h>
 #include <math.h>
@@ -220,7 +219,7 @@ Eina_Bool object_has_modal_role(AtspiRole role)
        return ret;
 }
 
-Eina_Bool object_has_defunct_state(AtspiAccessible *obj)
+static Eina_Bool _object_has_state(AtspiAccessible *obj, AtspiStateType state)
 {
        if (!obj)
                return EINA_FALSE;
@@ -229,25 +228,25 @@ Eina_Bool object_has_defunct_state(AtspiAccessible *obj)
 
        AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
 
-       if (atspi_state_set_contains(ss, ATSPI_STATE_DEFUNCT))
+       if (atspi_state_set_contains(ss, state))
                ret = EINA_TRUE;
        g_object_unref(ss);
        return ret;
 }
 
-Eina_Bool object_has_highlighted_state(AtspiAccessible *obj)
+Eina_Bool object_has_defunct_state(AtspiAccessible *obj)
 {
-       if (!obj)
-               return EINA_FALSE;
-
-       Eina_Bool ret = EINA_FALSE;
+       return _object_has_state(obj, ATSPI_STATE_DEFUNCT);
+}
 
-       AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
+Eina_Bool object_has_focused_state(AtspiAccessible *obj)
+{
+       return _object_has_state(obj, ATSPI_STATE_FOCUSED);
+}
 
-       if (atspi_state_set_contains(ss, ATSPI_STATE_HIGHLIGHTED))
-               ret = EINA_TRUE;
-       g_object_unref(ss);
-       return ret;
+Eina_Bool object_has_highlighted_state(AtspiAccessible *obj)
+{
+       return _object_has_state(obj, ATSPI_STATE_HIGHLIGHTED);
 }
 
 int get_percent_value(double value, double lower, double upper)
@@ -292,3 +291,18 @@ Eina_Bool is_same_str (const char *s1, const char *s2)
 
   return !strncmp (s1, s2, l1);
 }
+
+Live_Region_Politeness try_parse_politeness(GHashTable *attrs)
+{
+       Live_Region_Politeness mode = ACCESSIBLE_LIVE_REGION_OFF;
+       if (attrs) {
+               const char *val = g_hash_table_lookup(attrs, "container-live");
+               DEBUG("got attributes, containter-live is '%s'", val);
+               if (val) {
+                       if (g_strcmp0(val, "polite") == 0) mode = ACCESSIBLE_LIVE_REGION_POLITE;
+                       else if (g_strcmp0(val, "assertive") == 0) mode = ACCESSIBLE_LIVE_REGION_ASSERTIVE;
+               }
+       }
+       DEBUG("speaking politeness mode is %d", mode);
+       return mode;
+}