This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch wl/browser-all
in repository enlightenment.

View the commit online.

commit 42349e2655b11135596a318dca33f8880eafbb52
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 10 21:29:40 2026 -0600

    e_comp_wl - a finger does not move when the surface under it does
    
    The pointer half of this reports the surface-local position again when a
    surface slides under a cursor that has not moved. Touch needed the same
    and had nothing to do it with: e_comp_wl kept no touch state at all, just
    the resource list, and the down/motion/up handlers passed the evas events
    straight through without remembering where any finger was.
    
    Keep the points that are down - device, canvas position, and the client
    they were delivered to - and re-report them from the move callback in the
    surface's new frame of reference. Per device rather than one remembered
    point, since wl_touch is multi-point and every event already carries the
    device that made it. Points are dropped when the client goes away, or they
    would name freed memory the next time that client moved.
    
    wlcs: 647 passed -> 650, no regressions. Fixes the touch variants of
    subsurface_moves_under_input_device once and twice.
    
    subsurface_moves_out_from_under_input_device is still failing and is not
    addressed here. It wants the touch focus to move to the parent surface
    once the subsurface has slid away, and wlcs reads that focus from the last
    wl_touch.down, so satisfying it means synthesising an up on one surface
    and a down on another in the middle of a gesture. A touch point belongs to
    the surface it went down on until it is released; breaking that would hand
    clients a spurious end-of-gesture, which is a worse bug than the one it
    fixes. Left for a decision rather than papered over.
---
 src/bin/e_comp_wl.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/e_comp_wl.h | 15 +++++++++
 2 files changed, 111 insertions(+)

diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index b9c2bea51..935b62b8f 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -526,6 +526,63 @@ _e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *
      }
 }
 
+/* Active touch points, keyed by device. */
+static E_Comp_Wl_Touch_Point *
+_e_comp_wl_touch_point_find(int device)
+{
+   E_Comp_Wl_Touch_Point *tp;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(e_comp_wl->touch.points, l, tp)
+     if (tp->device == device) return tp;
+
+   return NULL;
+}
+
+static void
+_e_comp_wl_touch_point_update(E_Client *ec, int device, Evas_Coord x, Evas_Coord y)
+{
+   E_Comp_Wl_Touch_Point *tp;
+
+   if (!(tp = _e_comp_wl_touch_point_find(device)))
+     {
+        tp = E_NEW(E_Comp_Wl_Touch_Point, 1);
+        if (!tp) return;
+        tp->device = device;
+        e_comp_wl->touch.points =
+          eina_list_append(e_comp_wl->touch.points, tp);
+     }
+   tp->ec = ec;
+   tp->x = x;
+   tp->y = y;
+}
+
+static void
+_e_comp_wl_touch_point_del(int device)
+{
+   E_Comp_Wl_Touch_Point *tp;
+
+   if (!(tp = _e_comp_wl_touch_point_find(device))) return;
+   e_comp_wl->touch.points = eina_list_remove(e_comp_wl->touch.points, tp);
+   free(tp);
+}
+
+/* A client can go away with fingers still on it - the points would then name
+ * freed memory. */
+static void
+_e_comp_wl_touch_points_drop(E_Client *ec)
+{
+   E_Comp_Wl_Touch_Point *tp;
+   Eina_List *l, *ll;
+
+   EINA_LIST_FOREACH_SAFE(e_comp_wl->touch.points, l, ll, tp)
+     {
+        if (tp->ec != ec) continue;
+        e_comp_wl->touch.points = eina_list_remove_list(e_comp_wl->touch.points, l);
+        free(tp);
+     }
+}
+
 static void
 _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
 {
@@ -566,6 +623,8 @@ _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
                            ec->comp_data->surface, ev->device, x, y);
         wl_touch_send_frame(res);
      }
+
+   _e_comp_wl_touch_point_update(ec, ev->device, ev->canvas.x, ev->canvas.y);
 }
 
 static void
@@ -596,6 +655,8 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
         wl_touch_send_up(res, serial, ev->timestamp, ev->device);
         wl_touch_send_frame(res);
      }
+
+   _e_comp_wl_touch_point_del(ev->device);
 }
 
 static void
@@ -625,6 +686,8 @@ _e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
         wl_touch_send_motion(res, ev->timestamp, ev->device, x, y);
         wl_touch_send_frame(res);
      }
+
+   _e_comp_wl_touch_point_update(ec, ev->device, ev->cur.canvas.x, ev->cur.canvas.y);
 }
 
 static void
@@ -848,6 +911,38 @@ _e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_U
         _e_comp_wl_send_mouse_move(ec, px, py,
                                    (unsigned int)lround(ecore_loop_time_get() * 1000));
      }
+
+   /* Same again for fingers already down on us. A touch point does not follow
+    * the surface, so the one that was over this spot is now over a different
+    * part of it, and only we know that. */
+   if (e_comp_wl->touch.points && ec->comp_data->surface &&
+       (!e_client_util_ignored_get(ec)))
+     {
+        E_Comp_Wl_Touch_Point *tp;
+        struct wl_resource *res;
+        Eina_List *ll;
+        struct wl_client *wc;
+
+        wc = wl_resource_get_client(ec->comp_data->surface);
+        EINA_LIST_FOREACH(e_comp_wl->touch.points, ll, tp)
+          {
+             Eina_List *rl;
+
+             if (tp->ec != ec) continue;
+
+             EINA_LIST_FOREACH(e_comp_wl->touch.resources, rl, res)
+               {
+                  if (wl_resource_get_client(res) != wc) continue;
+                  if (!e_comp_wl_input_touch_check(res)) continue;
+                  wl_touch_send_motion(res,
+                                       (unsigned int)lround(ecore_loop_time_get() * 1000),
+                                       tp->device,
+                                       wl_fixed_from_int(tp->x - ec->client.x),
+                                       wl_fixed_from_int(tp->y - ec->client.y));
+                  wl_touch_send_frame(res);
+               }
+          }
+     }
 }
 
 static void
@@ -2840,6 +2935,7 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
    if (ec == e_comp_wl->wl.client_ec)
      e_comp_wl->wl.client_ec = NULL;
    e_comp_wl_extension_pointer_unconstrain(ec);
+   _e_comp_wl_touch_points_drop(ec);
 
    /* remove sub list */
    EINA_LIST_FREE(ec->comp_data->sub.list, subc)
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 596cd9de1..d21dc1651 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -151,6 +151,16 @@ typedef struct E_Comp_Wl_Extension_Data
      } efl_aux_hints;
 } E_Comp_Wl_Extension_Data;
 
+/* A finger that is currently down: which device it is, where it is on the
+ * canvas, and the client we told about it. Kept so that a surface moving
+ * under a stationary finger can be re-reported in its new coordinates. */
+typedef struct _E_Comp_Wl_Touch_Point
+{
+   int        device;
+   Evas_Coord x, y;
+   E_Client  *ec;
+} E_Comp_Wl_Touch_Point;
+
 struct _E_Comp_Wl_Data
 {
    Ecore_Wl2_Display *ewd;
@@ -222,6 +232,11 @@ struct _E_Comp_Wl_Data
    struct
      {
         Eina_List *resources;
+        /* Points currently down, one entry per device. wl_touch is
+         * multi-point, and down/motion/up all carry the device that made
+         * them, so a single remembered point would be wrong the moment a
+         * second finger arrives. */
+        Eina_List *points;
         Eina_Bool enabled E_BITFIELD;
      } touch;
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to