Remember the last touch position for HighlightedObjectInfo 76/303776/2 accepted/tizen/7.0/unified/20240129.164611
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 16:55:40 +0000 (17:55 +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 10820639d842cf73e4b0a386a1fa6510e0fad08d..f7c1ba8186a53b90a2a95acc4b1ddd4ac3b2c5d6 100644 (file)
@@ -146,6 +146,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 f9d48d3d3fcf4f23cce86fdff6d93105bca28e68..c9334da354ad0f6b9c7b642932af2150a7166f8c 100644 (file)
@@ -293,8 +293,16 @@ TIZEN_PROD_STATIC void _send_highlighted_object_info(NavigatorData *nd, AtspiAcc
                AtspiComponent *comp = atspi_accessible_get_component_iface(obj);
                AtspiRect *rect = atspi_component_get_extents(comp, ATSPI_COORD_TYPE_SCREEN, NULL);
 
-               highlighted_object_x = rect->x + rect->width / 2;
-               highlighted_object_y = rect->y + rect->height / 2;
+               if (rect_contains(rect, 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 = rect->x + rect->width / 2;
+                       highlighted_object_y = rect->y + rect->height / 2;
+               }
 
                g_boxed_free(ATSPI_TYPE_RECT, rect);
                g_object_unref(comp);
@@ -568,6 +576,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 8f9f069b5d26620b0df644ff989bfb642af90178..5dfc7dcb9508d6be015631c381e4e36683261142 100644 (file)
@@ -292,6 +292,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;