Remember the last touch position for HighlightedObjectInfo 71/303771/1
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 4 Jan 2024 15:12:08 +0000 (16:12 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Thu, 4 Jan 2024 15:12:08 +0000 (16:12 +0100)
The previous calculation method was to always use the center point of a given
actor, regardless of the position of the touch event that caused it to be
focused. In the tricky scenario where a smaller actor is overlaid on top of a
bigger actor such that the smaller actor covers the center of the bigger actor,
a double-tap-and-hold gesture meant to activate the bigger actor would activate
the smaller actor instead.

The calculation method introduced by this patch is a little bit better, but
still not ideal. However, the HighlightedObjectInfo D-Bus method has only two
parameters, the coordinates, which are then routed back into the app as a touch
event, so there isn't much more that could be done to address this issue.

The logic is ported from: https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-toolkit/+/288516/

Change-Id: Ia99d48bf1f952975cf55e79f5973fb45de5a306e

include/utils.h
src/navigator.c
src/utils.c

index 7438c2e99efd315a2219fc0cdcacdbbd36bd1283..de6c9a6450a321764cd2c62df8b21e1f9d3f71d5 100644 (file)
@@ -148,6 +148,7 @@ Eina_Bool object_get_position_in_table(AtspiAccessible *object, int *row, int *c
 int get_percent_value(double value, double lower, double upper);
 
 Eina_Bool is_same_str (const char *s1, const char *s2);
+Eina_Bool rect_contains(const AtspiRect *rect, int x, int y);
 
 Live_Region_Politeness try_parse_politeness(GHashTable *attrs, Eina_Bool assertive_by_default);
 
index e6a700153f3fae3225288862024067d7fc82bbd0..298e3c643480e86da8aa0dcff253442a2c635780 100644 (file)
@@ -292,8 +292,17 @@ TIZEN_PROD_STATIC void _send_highlighted_object_info(NavigatorData *nd, AtspiAcc
        if (role != ATSPI_ROLE_POPUP_MENU && role != ATSPI_ROLE_DIALOG) { /* ctxpopup outline does not show highlight frame */
                AtspiRect extents;
                object_get_extents(obj, &extents);
-               highlighted_object_x = extents.x + extents.width / 2;
-               highlighted_object_y = extents.y + extents.height / 2;
+
+               if (rect_contains(&extents, nd->last_focus.x, nd->last_focus.y)) {
+                       // If the last touched position is within the extents of the object,
+                       // then use that position. (The center may be covered by some other object).
+                       highlighted_object_x = nd->last_focus.x;
+                       highlighted_object_y = nd->last_focus.y;
+               } else {
+                       // Otherwise, use the center point.
+                       highlighted_object_x = extents.x + extents.width / 2;
+                       highlighted_object_y = extents.y + extents.height / 2;
+               }
        }
 
        keyboard_status = keyboard_event_status(nd->keyboard_tracker_data, info->resource_id);
@@ -564,6 +573,8 @@ TIZEN_PROD_STATIC void _focus_widget(NavigatorData *nd, Gesture_Info *info)
                if (val == APP_TRACKER_CONTEXT_NOT_VALID)
                        goto end;
 
+               nd->last_focus.x = info->x_beg;
+               nd->last_focus.y = info->y_beg;
                _current_highlight_object_set(nd, obj, info->type == ONE_FINGER_SINGLE_TAP ? HIGHLIGHT_POINT_AGAIN : HIGHLIGHT_POINT);
        }
 end:
index d382c57403275fe4ac339c7500176617051fcd17..41bd632d9a293b7b8af22d6af23193fdbfb106b4 100644 (file)
@@ -318,6 +318,17 @@ Eina_Bool is_same_str (const char *s1, const char *s2)
   return !strncmp (s1, s2, l1);
 }
 
+Eina_Bool rect_contains(const AtspiRect *rect, int x, int y)
+{
+       if (x < rect->x || x > (rect->x + rect->width))
+               return EINA_FALSE;
+
+       if (y < rect->y || y > (rect->y + rect->height))
+               return EINA_FALSE;
+
+       return EINA_TRUE;
+}
+
 Live_Region_Politeness try_parse_politeness(GHashTable *attrs, Eina_Bool assertive_by_default)
 {
        Live_Region_Politeness mode = assertive_by_default ? ACCESSIBLE_LIVE_REGION_ASSERTIVE : ACCESSIBLE_LIVE_REGION_OFF;