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 0247b18b4fe23da567e5cb77f2d0c6d7fa0d23ff
Author: Cedric BAIL <[email protected]>
AuthorDate: Tue Aug 11 16:48:26 2026 -0600
tests - let a test move the pointer by a delta, not just to a point
wlcs drives the pointer both ways: move_to() is absolute, move_by() is a
delta, and they arrive at the integration as two different entry points.
wl_test only spoke absolute, so the shim turned every delta into a
position by adding it to a copy of the pointer location it kept itself.
That copy is right exactly as long as nothing but the harness moves the
pointer - and a pointer constraint moves the pointer, which is its entire
job. Once E has held a confined pointer at an edge, the shim's tally and
the pointer's real position have parted company, and every subsequent
delta is measured from a place the pointer is not. Concretely: push a
pointer 600px past the corner of a 300px surface, and E holds it at
299,299 while the shim believes 750,750. Pull back by 600 and the shim
asks for 150,150 - inside the surface, so nothing is clamped and the
pointer lands in the middle, where a real one would have travelled to the
opposite edge and stopped at 0,0.
So say the delta and let the compositor decide where it lands, which is
what a pointing device does. The module applies it to E's own idea of
where the pointer is, and with that the last of the constraint tests
passes: confined_pointer_movement_is_constrained walks all four corners.
While here, stop tracking the pointer position in the module for the same
reason, and ask evas instead - including for the synthesised button event,
which was carrying the stale copy.
wlcs PointerConstraints+RelativePointer: 17 passed -> 18, none failing.
Note for whoever measures next: when_surface_is_reselected_persistent_-
confined_pointer_gets_notifications is a flake, seen failing once in three
runs of one unchanged binary. It creates and destroys surfaces in a loop
and depends on focus settling between them. Discount it in both
directions, as with ClientSurfaceEventsTest.frame_timestamp_increases.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01W6z4GbxmqypzCzUHPwzFMd
---
src/modules/wl_test/e_mod_main.c | 56 ++++++++++++++++++++++++++--------------
src/protocol/wl-test.xml | 20 +++++++++++++-
src/tests/wlcs/e_wlcs.c | 11 +++++---
3 files changed, 63 insertions(+), 24 deletions(-)
diff --git a/src/modules/wl_test/e_mod_main.c b/src/modules/wl_test/e_mod_main.c
index dbb833bc1..d0bab7168 100644
--- a/src/modules/wl_test/e_mod_main.c
+++ b/src/modules/wl_test/e_mod_main.c
@@ -124,15 +124,23 @@ _wl_test_cb_zone_add(struct wl_client *client EINA_UNUSED, struct wl_resource *r
ERR("wl_test: could not create wl_output for zone %d", num);
}
-/* Where the synthesised pointer is. E's manager-level input handlers are fed
- * ecore events, which carry coordinates the way libinput would; the evas feed
- * below does not, so remember them here. */
-static int _pointer_x = 0, _pointer_y = 0;
+/* Where the pointer is, asked of E rather than remembered here. A module-side
+ * tally is only right while nothing but this module moves the pointer, and a
+ * constraint does: once one has held the pointer at an edge, E's answer and
+ * the caller's arithmetic have parted company, and E's is the true one. */
+static void
+_pointer_xy_get(int *x, int *y)
+{
+ evas_pointer_canvas_xy_get(e_comp->evas, x, y);
+}
static void
-_wl_test_cb_pointer_warp(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t x, int32_t y)
+_pointer_motion(int x, int y)
{
E_Client *focused;
+ int px, py;
+
+ _pointer_xy_get(&px, &py);
/* Feeding evas delivers to the client: E's wayland pointer handlers are
* evas callbacks on the client's frame object, so a synthesised evas event
@@ -151,33 +159,41 @@ _wl_test_cb_pointer_warp(struct wl_client *client EINA_UNUSED, struct wl_resourc
* Same shape as the button case below, so the same remedy: call what the
* manager would have called, in the order it would have called it. */
focused = e_client_focused_get();
- if (focused && (!e_comp_util_mouse_grabbed()) &&
- ((x != _pointer_x) || (y != _pointer_y)))
+ if (focused && (!e_comp_util_mouse_grabbed()) && ((x != px) || (y != py)))
{
/* Unaccelerated equals accelerated here: there is no pointer
* acceleration in front of synthesised input, so reporting 0 for the
* unaccelerated pair was not "unknown", it was wrong. */
if ((!e_comp->screen) || (!e_comp->screen->relative_motion))
e_comp_wl_extension_relative_motion_event(ecore_time_unix_get() * 1000ULL,
- x - _pointer_x, y - _pointer_y,
- x - _pointer_x, y - _pointer_y);
+ x - px, y - py, x - px, y - py);
/* A constraint that swallows the motion has already warped the pointer
* somewhere of its own choosing, and the canvas must not then be told
- * it went where the test asked. The real handler answers
+ * it went where the caller asked. The real handler answers
* ECORE_CALLBACK_CANCEL at this point for the same reason. */
if (e_comp_wl_extension_pointer_constraints_update(focused, x, y))
- {
- evas_pointer_canvas_xy_get(e_comp->evas, &_pointer_x, &_pointer_y);
- return;
- }
+ return;
}
- _pointer_x = x;
- _pointer_y = y;
evas_event_feed_mouse_move(e_comp->evas, x, y, 0, NULL);
}
+static void
+_wl_test_cb_pointer_warp(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t x, int32_t y)
+{
+ _pointer_motion(x, y);
+}
+
+static void
+_wl_test_cb_pointer_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t dx, int32_t dy)
+{
+ int px, py;
+
+ _pointer_xy_get(&px, &py);
+ _pointer_motion(px + dx, py + dy);
+}
+
static void
_wl_test_cb_pointer_button(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, uint32_t button, uint32_t pressed)
{
@@ -204,8 +220,9 @@ _wl_test_cb_pointer_button(struct wl_client *client EINA_UNUSED, struct wl_resou
* e_client_focused_get() whether the grab holder is focused, so it has to
* run before the evas feed moves focus to whatever was clicked. */
memset(&ev, 0, sizeof(ev));
- ev.x = ev.root.x = _pointer_x;
- ev.y = ev.root.y = _pointer_y;
+ _pointer_xy_get(&ev.x, &ev.y);
+ ev.root.x = ev.x;
+ ev.root.y = ev.y;
ev.buttons = b;
ev.multi.device = 0;
if (e_comp_wl_grab_client_mouse_button(&ev) == ECORE_CALLBACK_DONE) return;
@@ -286,6 +303,7 @@ static const struct wl_test_interface _wl_test_implementation =
_wl_test_cb_move_surface,
_wl_test_cb_zone_add,
_wl_test_cb_pointer_warp,
+ _wl_test_cb_pointer_move,
_wl_test_cb_pointer_button,
_wl_test_cb_pointer_axis,
_wl_test_cb_touch_down,
@@ -332,7 +350,7 @@ e_modapi_init(E_Module *m)
wl_display_add_client_created_listener(e_comp_wl->wl.disp,
&_client_created_listener);
- _wl_test_global = wl_global_create(e_comp_wl->wl.disp, &wl_test_interface, 1,
+ _wl_test_global = wl_global_create(e_comp_wl->wl.disp, &wl_test_interface, 2,
NULL, _wl_test_cb_bind);
if (!_wl_test_global)
{
diff --git a/src/protocol/wl-test.xml b/src/protocol/wl-test.xml
index 6cbdd5be6..e40d5b193 100644
--- a/src/protocol/wl-test.xml
+++ b/src/protocol/wl-test.xml
@@ -23,7 +23,7 @@
DEALINGS IN THE SOFTWARE.
</copyright>
- <interface name="wl_test" version="1">
+ <interface name="wl_test" version="2">
<description summary="private interface for the compositor test suite">
A back door into the compositor for its own test suite. It exposes
internal state and synthesises input, so it is deliberately NOT built
@@ -131,6 +131,24 @@
<arg name="y" type="int"/>
</request>
+ <request name="pointer_move" since="2">
+ <description summary="move the pointer by a delta">
+ Not the same thing as warping to a position the caller worked out
+ itself, and the difference is the whole of pointer confinement: a real
+ pointing device reports a delta, and where that lands is the
+ compositor's answer, not the caller's. Once the compositor has held a
+ confined pointer at an edge, the two disagree about where the pointer
+ is, and every further delta a caller turns into an absolute position is
+ measured from the wrong place - so a pointer pushed past a corner and
+ pulled back never reaches the opposite edge.
+
+ Deltas are also what the relative-pointer protocol reports, which is
+ the other reason a test needs to be able to express one.
+ </description>
+ <arg name="dx" type="int"/>
+ <arg name="dy" type="int"/>
+ </request>
+
<request name="pointer_button">
<description summary="press or release a pointer button">
Button numbers are the linux/input.h BTN_* codes the seat already
diff --git a/src/tests/wlcs/e_wlcs.c b/src/tests/wlcs/e_wlcs.c
index adda96bf7..2be87ee4d 100644
--- a/src/tests/wlcs/e_wlcs.c
+++ b/src/tests/wlcs/e_wlcs.c
@@ -106,7 +106,7 @@ _registry_global(void *data, struct wl_registry *reg, uint32_t id,
(void)version;
if (!strcmp(iface, "wl_test") && !*out)
- *out = wl_registry_bind(reg, id, &wl_test_interface, 1);
+ *out = wl_registry_bind(reg, id, &wl_test_interface, 2);
}
static void
@@ -533,12 +533,15 @@ _pointer_move_relative(WlcsPointer *pointer, wl_fixed_t dx, wl_fixed_t dy)
{
E_Pointer *p = (E_Pointer *)pointer;
- /* The compositor only takes absolute positions, so the current location is
- * tracked here. */
+ /* Sent as a delta rather than added to a position tracked here. The two are
+ * the same right up until the compositor puts the pointer somewhere the
+ * caller did not ask for - which is exactly what a pointer constraint does -
+ * and from then on every absolute position computed here is measured from a
+ * place the pointer is not. */
p->x += wl_fixed_to_int(dx);
p->y += wl_fixed_to_int(dy);
if (!p->server->ctrl_test) return;
- wl_test_pointer_warp(p->server->ctrl_test, p->x, p->y);
+ wl_test_pointer_move(p->server->ctrl_test, wl_fixed_to_int(dx), wl_fixed_to_int(dy));
wl_display_roundtrip(p->server->ctrl);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.