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 eb838d2d6659e4469225fb49203eaad7046546b4
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 10 16:51:45 2026 -0600
e_comp_wl - a subsurface position belongs to its parent's commit
wl_subsurface.set_position schedules state on the parent surface, not on
the subsurface itself: the coordinates take effect whenever the state of
the parent surface is applied. We stored them straight into sdata->position
with set = TRUE at request time, and _e_comp_wl_subsurface_parent_commit()
applied them on any recursive pass that reached the client.
That is fine one level down, where the pass only happens because the parent
did commit. It is wrong two levels down. A commit on the grandparent walks
through a synchronized parent into its children, and there it applied a
position the parent had never committed - so a set_position that nothing
had scheduled yet took effect anyway, and a menu that had asked to move
later moved now.
Give the position the third stage it needs. The request lands in pending;
the parent's own commit latches it into position; whoever applies the
parent's state applies position and clears set, leaving x and y as the
coordinates in effect - which is what _e_comp_wl_evas_cb_move() reads when
the parent moves and the children have to follow, so that keeps working.
Latching in _e_comp_wl_surface_cb_commit(), before the subsurface branch
returns, covers both the subsurface and the toplevel commit paths.
wlcs SubsurfaceMultilevelTest: subsurface_with_sync_parent_does_not_move_
when_only_grandparent_committed and subsurface_does_not_move_when_grand
parent_commit_is_before_sync_parent_commit now pass on all four shells,
8 tests, with no regressions across the full suite.
---
src/bin/e_comp_wl.c | 39 ++++++++++++++++++++++++++++++++++++---
src/bin/e_comp_wl.h | 11 +++++++++++
2 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 1318e05b7..964508eb4 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -1953,6 +1953,35 @@ _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, str
}
}
+/* Latch the positions our subsurfaces have asked for. A subsurface's position
+ * is part of its parent's double-buffered state, so this commit - the
+ * parent's - is what schedules it; whether it then takes effect now or waits
+ * for a sync parent further up is decided afterwards, by whoever applies that
+ * state. Latching here is what keeps the two apart: an unrelated commit higher
+ * in the tree walks down through this client, and without a latch it would
+ * apply a position the parent has never committed. */
+static void
+_e_comp_wl_subsurface_positions_latch(E_Client *ec)
+{
+ E_Client *subc;
+ Eina_List *l;
+
+ EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
+ {
+ E_Comp_Wl_Subsurf_Data *sdata;
+
+ if (ec == subc) continue;
+ if (!subc->comp_data) continue;
+ if (!(sdata = subc->comp_data->sub.data)) continue;
+ if (!sdata->pending_position.set) continue;
+
+ sdata->position.x = sdata->pending_position.x;
+ sdata->position.y = sdata->pending_position.y;
+ sdata->position.set = EINA_TRUE;
+ sdata->pending_position.set = EINA_FALSE;
+ }
+}
+
static void
_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
@@ -1962,6 +1991,8 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res
if (!(ec = wl_resource_get_user_data(resource))) return;
if (e_object_is_del(E_OBJECT(ec))) return;
+ _e_comp_wl_subsurface_positions_latch(ec);
+
if (e_comp_wl_subsurface_commit(ec)) return;
e_comp_wl_surface_commit(ec);
@@ -2423,9 +2454,11 @@ _e_comp_wl_subsurface_cb_position_set(struct wl_client *client EINA_UNUSED, stru
if (!(sdata = ec->comp_data->sub.data)) return;
- sdata->position.x = x;
- sdata->position.y = y;
- sdata->position.set = EINA_TRUE;
+ /* Pending, not scheduled: these coordinates belong to the parent's state,
+ * so it is the parent's next commit that latches them. */
+ sdata->pending_position.x = x;
+ sdata->pending_position.y = y;
+ sdata->pending_position.set = EINA_TRUE;
}
static void
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 3388d74ce..596cd9de1 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -92,6 +92,17 @@ struct _E_Comp_Wl_Subsurf_Data
E_Client *parent;
+ /* wl_subsurface.set_position schedules state on the PARENT surface, not on
+ * this one, so it travels in three stages. The request lands in pending;
+ * the parent's own commit latches it into position; whatever applies the
+ * parent's state then applies position and clears set, leaving x and y as
+ * the coordinates currently in effect. */
+ struct
+ {
+ int x, y;
+ Eina_Bool set;
+ } pending_position;
+
struct
{
int x, y;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.