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 a7800a74ce4e5cda5618083e486c6b9dd9683b70
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 17 19:06:44 2026 -0600
tests - wait for a browser to stop moving before believing its geometry
tk_wait_state returns when a state bit flips. For a client this suite wrote
that is the whole story; for a browser it is the first of two events, because
E sends a configure and the client repaints at its own pace some frames later.
A test reading x/y/w/h in between reads the old size and cannot tell.
tk_wait_quiet closes that gap by waiting for quiescence - no move or resize
for quiet_ms - which is the only signal available from outside, since only the
client knows when it has finished responding.
Being straight about what this did and did not find: it was written to test
the theory that the browser flakiness was a premature baseline, and it refuted
it. E_TEST_SETTLE_TRACE=1 reports every settle, and across 18 samples covering
all three browsers it saw zero changes in every quiet window. Nothing was
still moving. The flakiness was in run-nested.sh's cleanup and is fixed
separately.
It stays because the gap it closes is real even though it was not the bug, and
because the trace is what makes the question answerable rather than arguable
the next time a browser test moves.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01FtoiXoSKUmZb6Aix6U3GZS
---
src/tests/wayland/e_wl_testkit.c | 57 ++++++++++++++++++++++++++++++++++++++++
src/tests/wayland/e_wl_testkit.h | 23 ++++++++++++++++
src/tests/wayland/test_browser.c | 24 ++++++++++++++++-
3 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/src/tests/wayland/e_wl_testkit.c b/src/tests/wayland/e_wl_testkit.c
index a8cd61531..31c31ca25 100644
--- a/src/tests/wayland/e_wl_testkit.c
+++ b/src/tests/wayland/e_wl_testkit.c
@@ -590,6 +590,63 @@ tk_wait_state(Tk *tk, const char *app_id, unsigned int mask, unsigned int want,
timeout_ms, what, last, want, mask);
}
+Tk_Client *
+tk_wait_quiet(Tk *tk, const char *app_id, int quiet_ms, int timeout_ms)
+{
+ double start = _now_ms();
+ double deadline = start + timeout_ms;
+ double quiet_since;
+ int x, y, w, h;
+ int x0, y0, w0, h0;
+ int changes = 0;
+ Tk_Client *c;
+ static int trace = -1;
+
+ if (trace < 0)
+ {
+ const char *e = getenv("E_TEST_SETTLE_TRACE");
+
+ trace = (e && (*e == '1')) ? 1 : 0;
+ }
+
+ c = tk_expect(tk, app_id);
+ x = x0 = c->x; y = y0 = c->y; w = w0 = c->w; h = h0 = c->h;
+ quiet_since = _now_ms();
+
+ for (;;)
+ {
+ tk_sync(tk);
+ c = tk_find(tk, app_id);
+ /* A window that went away is not this function's business to judge.
+ * Hand the caller tk_expect's failure, which says so properly. */
+ if (!c) return tk_expect(tk, app_id);
+
+ if ((c->x != x) || (c->y != y) || (c->w != w) || (c->h != h))
+ {
+ x = c->x; y = c->y; w = c->w; h = c->h;
+ quiet_since = _now_ms();
+ changes++;
+ }
+ else if ((_now_ms() - quiet_since) >= quiet_ms) break;
+
+ if (_now_ms() >= deadline)
+ {
+ if (trace)
+ printf("tk_wait_quiet: '%s' never went quiet in %dms, last "
+ "%dx%d+%d+%d after %d change(s)\n",
+ app_id, timeout_ms, w, h, x, y, changes);
+ break;
+ }
+ }
+
+ if (trace)
+ printf("tk_wait_quiet: '%s' %dx%d+%d+%d -> %dx%d+%d+%d, %d change(s) "
+ "over %.0fms\n", app_id, w0, h0, x0, y0, w, h, x, y, changes,
+ _now_ms() - start);
+
+ return tk_expect(tk, app_id);
+}
+
void
tk_zone_add(Tk *tk, int x, int y, int w, int h)
{
diff --git a/src/tests/wayland/e_wl_testkit.h b/src/tests/wayland/e_wl_testkit.h
index a54fc4937..1d494584b 100644
--- a/src/tests/wayland/e_wl_testkit.h
+++ b/src/tests/wayland/e_wl_testkit.h
@@ -146,6 +146,29 @@ Tk_Client *tk_wait_window(Tk *tk, const char *app_id_part, int timeout_ms);
Tk_Client *tk_wait_state(Tk *tk, const char *app_id, unsigned int mask,
unsigned int want, int timeout_ms, const char *what);
+/* Wait until a window's geometry stops changing: no movement or resize for
+ * quiet_ms, or give up after timeout_ms and return the last thing seen.
+ *
+ * tk_wait_state is not enough for a client this suite did not write, and the
+ * difference is where the browser tests were losing. A state change and the
+ * resize that follows it are two separate events on the wire - E sends a
+ * configure, the client redraws at its own pace, and only then does the
+ * geometry catch up. tk_wait_state returns on the first of those, so a test
+ * that reads x/y/w/h straight afterwards can read the *old* size and not know
+ * it. Measured on this machine: chromium reports itself unmaximized while
+ * still 972x716, and arrives at its real 940x684 a few hundred ms later.
+ *
+ * That is not a compositor bug and cannot be fixed by waiting longer in one
+ * place - it is the difference between "the state changed" and "the client
+ * finished responding to it", and only the client knows when the second has
+ * happened. Quiescence is the only signal available from outside.
+ *
+ * Set E_TEST_SETTLE_TRACE=1 to print every settle: what it started at, what it
+ * ended at, and how long it took. That is what this was written to prove, and
+ * it is worth being able to show again rather than trusting this comment. */
+Tk_Client *tk_wait_quiet(Tk *tk, const char *app_id, int quiet_ms,
+ int timeout_ms);
+
/* Add a zone - a second monitor - to the compositor's right. The backends all
* come up with exactly one, so anything about moving a window between screens
* needs this to have something to move it to. */
diff --git a/src/tests/wayland/test_browser.c b/src/tests/wayland/test_browser.c
index 3eb82450e..5328b6ae1 100644
--- a/src/tests/wayland/test_browser.c
+++ b/src/tests/wayland/test_browser.c
@@ -38,6 +38,15 @@ static int settle_ms = 30000;
#define APPEAR_MS appear_ms
#define SETTLE_MS settle_ms
+/* How long a browser has to hold still before its geometry is believed. Long
+ * enough to span the gap between "E said maximize" and "the browser finished
+ * repainting at the new size", which is one client round trip plus however
+ * long it takes to redraw a page - hundreds of milliseconds here, and not
+ * bounded by anything the compositor controls. Scales with E_TEST_BROWSER_SLOW
+ * along with everything else. */
+static int quiet_ms = 700;
+#define QUIET_MS quiet_ms
+
#define MAXIMIZED (WL_TEST_CLIENT_STATE_MAXIMIZED_H | \
WL_TEST_CLIENT_STATE_MAXIMIZED_V)
@@ -56,7 +65,7 @@ main(int argc, char **argv)
const char *slow = getenv("E_TEST_BROWSER_SLOW");
int mult = slow ? atoi(slow) : 1;
- if (mult > 1) appear_ms *= mult, settle_ms *= mult;
+ if (mult > 1) appear_ms *= mult, settle_ms *= mult, quiet_ms *= mult;
}
tk = tk_connect("test-browser");
@@ -86,6 +95,17 @@ main(int argc, char **argv)
"the browser to start out unmaximized");
}
+ /* And then wait for it to stop moving, which is a different thing, and is
+ * where this test was losing runs. tk_wait_state returns when the state bit
+ * flips; the browser repaints at the size it wants some frames after that.
+ * A baseline taken in between is a number no client ever agreed to, and
+ * every later comparison is against it - which is why the unmaximize
+ * assertion below used to fail by exactly the amount the baseline was
+ * wrong by. Measured: chromium says unmaximized at 972x716, settles at
+ * 940x684, and the failure read "unmaximized to 940x684, started at
+ * 972x716". */
+ c = tk_wait_quiet(tk, app_id, QUIET_MS, SETTLE_MS);
+
x0 = c->x; y0 = c->y; w0 = c->w; h0 = c->h;
printf("test-browser: baseline %dx%d+%d+%d title='%s'\n",
w0, h0, x0, y0, c->title);
@@ -125,6 +145,7 @@ main(int argc, char **argv)
tk_action(tk, id, "window_maximized_toggle", NULL);
c = tk_wait_state(tk, app_id, MAXIMIZED, MAXIMIZED, SETTLE_MS,
"the browser to report itself maximized");
+ c = tk_wait_quiet(tk, app_id, QUIET_MS, SETTLE_MS);
mw = c->w; mh = c->h;
if ((mw <= w0) && (mh <= h0))
tk_fail(tk, "maximized to %dx%d, no bigger than the %dx%d it started at",
@@ -133,6 +154,7 @@ main(int argc, char **argv)
tk_action(tk, id, "window_maximized_toggle", NULL);
c = tk_wait_state(tk, app_id, MAXIMIZED, 0, SETTLE_MS,
"the browser to come back from maximized");
+ c = tk_wait_quiet(tk, app_id, QUIET_MS, SETTLE_MS);
if ((c->w != w0) || (c->h != h0) || (c->x != x0) || (c->y != y0))
tk_fail(tk, "unmaximized to %dx%d+%d+%d, started at %dx%d+%d+%d",
c->w, c->h, c->x, c->y, w0, h0, x0, y0);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.