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 84d4f11111bb3b3e88f6b4ae14bf44fb40322edc
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 10 18:37:54 2026 -0600
e_comp_wl - a subsurface's z-order has to reach the canvas
sub.list holds the sub-surfaces of a parent in bottom-to-top order, and
almost nothing was copying that order down to evas - which is what
actually gets drawn and hit-tested. Two ways it went wrong:
A new sub-surface was stacked directly on its parent. It is appended to
sub.list, i.e. top-most of its siblings, but evas_object_stack_above()
against the parent puts it underneath every sibling that came before it,
so the canvas ended up in the exact reverse of the recorded order.
place_above and place_below reordered sub.list and set sub.restack_target,
and sub.restack_target was read nowhere in the tree. Nothing restacked, so
the requests changed our bookkeeping and nothing else. They only appeared
to work because the two bugs cancel out in the simple two-sibling case:
the reversed creation order already had the surface on top that
place_above was being asked to raise.
Pull the ordering out of the restack callback into
_e_comp_wl_subsurface_stack_sync() and use it in both places. Applying the
pending restack from _e_comp_wl_surface_state_commit() also gets the
double-buffering right: wl_subsurface says the z-order is double-buffered
and takes effect the next time the state of the parent surface is applied,
not when the request arrives.
No wlcs test covers any of this - place_above_simple and place_below_simple
cannot pass on any compositor, since they assert that neither of two
overlapping sub-surfaces has the pointer. Verified by instrumenting evas
directly: the canvas order now follows sub.list, and does so at the
parent's commit rather than at the request. Full wlcs suite is unchanged
either way, 640 passed / 99 failed before and after.
---
src/bin/e_comp_wl.c | 49 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 964508eb4..96e7b21a5 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -769,19 +769,17 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
_e_comp_wl_keyboard_leave(ec);
}
+/* Put our subsurfaces on the canvas in the order sub.list holds them: the list
+ * runs bottom to top, so its last entry is the one nearest the viewer. This is
+ * the only thing that makes the list mean anything - evas is what gets drawn
+ * and what gets hit-tested, so a sub.list nobody has copied down to the canvas
+ * is just bookkeeping. */
static void
-_e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+_e_comp_wl_subsurface_stack_sync(E_Client *ec)
{
- E_Client *sec, *ec = data;
+ E_Client *sec;
Eina_List *l, *ll;
- if (e_object_is_del(E_OBJECT(ec))) return;
- if (e_client_has_xwindow(ec)) return;
-
- /* only restack to enforce shell spec if config would otherwise not force restack */
- if (!e_config->transient.raise)
- e_client_transients_restack(ec);
-
if (!ec->comp_data->sub.list) return;
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, sec)
evas_object_layer_set(sec->frame, evas_object_layer_get(ec->frame));
@@ -796,6 +794,21 @@ _e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EIN
}
}
+static void
+_e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ E_Client *ec = data;
+
+ if (e_object_is_del(E_OBJECT(ec))) return;
+ if (e_client_has_xwindow(ec)) return;
+
+ /* only restack to enforce shell spec if config would otherwise not force restack */
+ if (!e_config->transient.raise)
+ e_client_transients_restack(ec);
+
+ _e_comp_wl_subsurface_stack_sync(ec);
+}
+
static void
_e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -1714,6 +1727,17 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
}
ec->comp_data->in_commit = 0;
+ /* Our children's z-order is our state, and this is us applying it. Doing
+ * the restack here rather than in place_above/place_below is what makes it
+ * double-buffered, which is what the protocol asks for: the requests only
+ * build up a pending order, and it becomes visible the next time the state
+ * of the parent surface is applied. */
+ if (ec->comp_data->sub.restack_target == ec)
+ {
+ ec->comp_data->sub.restack_target = NULL;
+ _e_comp_wl_subsurface_stack_sync(ec);
+ }
+
_e_comp_wl_surface_outputs_update(ec);
}
@@ -2629,8 +2653,13 @@ _e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl
ec->comp_data->sub.data = ""
if (epc)
{
+ /* A new sub-surface is the top-most of its siblings, which is where
+ * the eina_list_append above just put it. Stacking it directly on the
+ * parent instead would bury it under every sibling that came before,
+ * leaving the canvas in the exact reverse of the order the list
+ * records. */
evas_object_layer_set(ec->frame, evas_object_layer_get(epc->frame));
- evas_object_stack_above(ec->frame, epc->frame);
+ _e_comp_wl_subsurface_stack_sync(epc);
}
return EINA_TRUE;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.