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 6670d2b4bae4b2e38ab486c036e87b1b9f869b3d
Author: Cedric BAIL <[email protected]>
AuthorDate: Tue Aug 11 16:44:23 2026 -0600
e_comp_wl - a null constraint region is the whole surface, not no region
zwp_pointer_constraints_v1 says a null region means the surface's input
region. E read it as the absence of a boundary: _inside_tiler() returns
true immediately for a NULL tiler, so a confined pointer was held by
nothing but the input area, and - the part that actually bites - the clamp
point was never computed, so a pointer leaving the surface got warped back
to where it came from instead of being held at the edge.
Give it a region to be inside: an implicit tiler covering the surface,
rebuilt when the surface is resized.
The same misreading is in set_region(). Asked for a null region it left an
*empty* tiler behind as the pending one, and empty is the opposite of what
was meant - nothing is inside it, so once that pending region was
committed the constraint could never activate again. "The whole surface"
is a value and needs saying, so carry it as a flag rather than inferring
it from a pending pointer that is also how "no change" is spelled.
Measured on its own: no change, 17 passed either way. It is the other half
of the diagonal clamp in the next commit, which cannot be reached without
a region to clamp to, and neither can be seen without the relative-motion
harness fix after it. Committed separately because they are three
different mistakes, not because each moves the number.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01W6z4GbxmqypzCzUHPwzFMd
---
src/bin/e_comp_wl_extensions.c | 52 ++++++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 9 deletions(-)
diff --git a/src/bin/e_comp_wl_extensions.c b/src/bin/e_comp_wl_extensions.c
index 24ba610f7..e2a83308d 100644
--- a/src/bin/e_comp_wl_extensions.c
+++ b/src/bin/e_comp_wl_extensions.c
@@ -35,17 +35,21 @@ typedef struct Constraint
struct wl_resource *surface;
Eina_Tiler *region;
Eina_Tiler *pending;
+ Eina_Tiler *implicit; // stands in for a null region, i.e. the whole surface
+ int iw, ih; // surface size `implicit` was built for
Evas_Point *pending_xy;
Evas_Point *pointer_xy;
Eina_Bool lock E_BITFIELD; // if not lock, confine
Eina_Bool persistent E_BITFIELD;
Eina_Bool active E_BITFIELD;
Eina_Bool dead E_BITFIELD; // oneshot, already deactivated once
+ Eina_Bool pending_region E_BITFIELD; // set_region since the last commit
} Constraint;
static Eina_List *active_constraints;
static Eina_Bool _inside_tiler(Eina_Tiler *r, Eina_Bool active, int x, int y, int px, int py, int *ax, int *ay);
+static Eina_Tiler *_constraint_region_get(Constraint *c);
/* A constraint becomes active when its surface holds the focus and the pointer
* is already inside it, and nothing has to move for that to become true: a
@@ -73,7 +77,7 @@ _constraints_activate(E_Client *ec)
int ax = 0, ay = 0;
if (c->active || c->dead) continue;
- if (!_inside_tiler(c->region, EINA_FALSE, px - ec->client.x, py - ec->client.y,
+ if (!_inside_tiler(_constraint_region_get(c), EINA_FALSE, px - ec->client.x, py - ec->client.y,
px - ec->client.x, py - ec->client.y, &ax, &ay))
continue;
c->active = 1;
@@ -455,6 +459,7 @@ _constraint_destroy(struct wl_resource *resource)
}
eina_tiler_free(c->pending);
eina_tiler_free(c->region);
+ eina_tiler_free(c->implicit);
free(c->pointer_xy);
free(c->pending_xy);
free(c);
@@ -475,20 +480,48 @@ _constraint_set_region(struct wl_resource *resource, struct wl_resource *region)
Eina_Tiler *r = NULL;
if (region) r = wl_resource_get_user_data(region);
- else E_FREE_FUNC(c->pending, eina_tiler_free);
- if (c->pending)
- eina_tiler_clear(c->pending);
- else
+ E_FREE_FUNC(c->pending, eina_tiler_free);
+ if (r)
{
c->pending = eina_tiler_new(65535, 65535);
eina_tiler_tile_size_set(c->pending, 1, 1);
+ eina_tiler_union(c->pending, r);
}
- if (r)
- eina_tiler_union(c->pending, r);
+ /* A null region means the whole surface. That is a value, not the absence
+ * of one, so it needs its own flag to survive the commit: leaving an empty
+ * tiler behind instead - which is what this did - means nothing is inside
+ * the region, and the constraint can never activate again. */
+ c->pending_region = 1;
_constraint_set_pending(c);
}
+/* Protocol: a null region is the surface's input region. Treating it as "no
+ * boundary at all" let a confined pointer go wherever the input area allowed
+ * and, worse, left the clamp point uncomputed - so a pointer leaving the
+ * surface was put back where it came from instead of being held at the edge. */
+static Eina_Tiler *
+_constraint_region_get(Constraint *c)
+{
+ Eina_Rectangle r;
+
+ if (c->region) return c->region;
+ if (!c->ec) return NULL;
+ if (c->implicit)
+ {
+ if ((c->iw == c->ec->client.w) && (c->ih == c->ec->client.h))
+ return c->implicit;
+ eina_tiler_free(c->implicit);
+ }
+ c->iw = c->ec->client.w;
+ c->ih = c->ec->client.h;
+ c->implicit = eina_tiler_new(65535, 65535);
+ eina_tiler_tile_size_set(c->implicit, 1, 1);
+ EINA_RECTANGLE_SET(&r, 0, 0, c->iw, c->ih);
+ eina_tiler_rect_add(c->implicit, &r);
+ return c->implicit;
+}
+
static void
_e_comp_wl_locked_pointer_v1_set_region(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region)
{
@@ -1149,11 +1182,12 @@ e_comp_wl_extension_pointer_constraints_commit(E_Client *ec)
if ((!ec) || (!ec->comp_data)) return;
EINA_LIST_FOREACH(ec->comp_data->constraints, l, c)
{
- if (c->pending)
+ if (c->pending_region)
{
eina_tiler_free(c->region);
c->region = c->pending;
c->pending = NULL;
+ c->pending_region = 0;
}
if (c->pending_xy)
{
@@ -1295,7 +1329,7 @@ e_comp_wl_extension_pointer_constraints_update(E_Client *ec, int x, int y)
EINA_LIST_FOREACH_SAFE(ec->comp_data->constraints, l, ll, c)
{
int ax = px - ec->client.x, ay = py - ec->client.y;
- Eina_Bool inside_region = _inside_tiler(c->region, c->active, x - ec->client.x, y - ec->client.y,
+ Eina_Bool inside_region = _inside_tiler(_constraint_region_get(c), c->active, x - ec->client.x, y - ec->client.y,
px - ec->client.x, py - ec->client.y, &ax, &ay);
if ((!c->active) && (!c->dead) && inside && inside_region)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.