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 2e4ae105337b99a8187ebb21fb41393abd04437e
Author: Cedric BAIL <[email protected]>
AuthorDate: Wed Aug 19 21:15:30 2026 -0600
e_utils - suppress test dialogs at the funnel, not at one caller
A test session has nobody to read a dialog, and a window appearing
unbidden takes the keyboard focus off whatever the test is driving.
That is not cosmetic: every assertion after it is about the wrong
window, and the failure names something unrelated. It cost a run of the
input-method tests, which reported that their own window "did not take
keyboard focus" while an error dialog sat on top holding it.
E_TEST_NO_DIALOGS already existed. 7f0fffc91 honoured it in e_system.c,
which covered the one dialog somebody had been bitten by - the
enlightenment_system spawn failure - and nothing else. The dialog that
stole focus came from somewhere else, and a per-caller guard covers
exactly the callers someone remembered.
Every error dialog in E arrives through e_util_dialog_internal;
e_util_dialog_show is a macro over it. So the guard goes there and one
check covers all of them.
**The message is not dropped, it moves.** A test session's channel for
"something went wrong" is the compositor log, which run-nested.sh prints
on failure, so what a person would have read in the dialog is still in
front of whoever is debugging - and it names itself, which is how the
next one will be identified without a bisect. Suppressing a fault report
silently would be hiding it; relocating it is not.
The guard in e_system.c stays. It is no longer load-bearing, but it also
stops the five-second timer being armed at all, which beats arming it in
order to log a line five seconds later.
The test raises a dialog from real compositor code rather than something
invented: E's own window_focus action, given a direction that does not
exist, calls e_util_dialog_show with an "Invalid parameter" message, and
wl_test.client_action can reach it. It then checks both halves - no
window with the _error_dialog app_id, and the test's own window still
focused, which is the property everything else depends on.
Removing the guard makes it fail and names the dialog exactly: "an error
dialog appeared (app_id '_error_dialog', title 'Error: window_focus
action', 215x125+404+332)". Checked against a build with it removed.
Measured: full wlcs 780 passed / 14 failed, failure set identical to
d63249c9d. In-tree 38 -> 39.
---
src/bin/e_system.c | 6 ++-
src/bin/e_utils.c | 25 +++++++++
src/tests/wayland/meson.build | 1 +
src/tests/wayland/test_no_dialogs.c | 103 ++++++++++++++++++++++++++++++++++++
4 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/src/bin/e_system.c b/src/bin/e_system.c
index e48da038f..bf627c4eb 100644
--- a/src/bin/e_system.c
+++ b/src/bin/e_system.c
@@ -119,8 +119,10 @@ static void
_system_spawn_error(int exit_code)
{
#ifdef E_TESTS
- /* a test compositor has nobody to read a dialog, and a window appearing
- * unbidden takes the focus off whatever the test is driving */
+ /* Not the only guard any more, and no longer the load-bearing one: every
+ * dialog is suppressed centrally in e_util_dialog_internal. This one stays
+ * because it also stops the five-second timer being armed at all, which is
+ * cheaper than arming it in order to log a line five seconds later. */
if (getenv("E_TEST_NO_DIALOGS")) return;
#endif
if (_error_dialog_timer) ecore_timer_del(_error_dialog_timer);
diff --git a/src/bin/e_utils.c b/src/bin/e_utils.c
index 4b34abba9..20da6bbb8 100644
--- a/src/bin/e_utils.c
+++ b/src/bin/e_utils.c
@@ -393,6 +393,31 @@ e_util_dialog_internal(const char *title, const char *txt)
{
E_Dialog *dia;
+#ifdef E_TESTS
+ /* A test session has nobody to read a dialog, and a window appearing
+ * unbidden takes the focus off whatever the test is driving - which is not
+ * cosmetic: every assertion after it is then about the wrong window, and
+ * the failure names something unrelated.
+ *
+ * The guard belongs here rather than at a call site. Every error dialog E
+ * raises arrives through this function - e_util_dialog_show is a macro over
+ * it - so one check covers all of them, where a per-caller check covers
+ * exactly the caller someone remembered. 7f0fffc91 put one in e_system.c
+ * and it is why the enlightenment_system dialog is quiet; the dialog that
+ * stole focus from an input-method test came from somewhere else.
+ *
+ * The message is not dropped, it moves. A test session's channel for
+ * "something went wrong" is the compositor log, which run-nested.sh prints
+ * on failure - so what a person would have read in the dialog is still in
+ * front of whoever is debugging, and it names itself. Suppressing it
+ * silently would be hiding a fault; relocating it is not. */
+ if (getenv("E_TEST_NO_DIALOGS"))
+ {
+ ERR("E_TEST_NO_DIALOGS: suppressed dialog: '%s': %s", title, txt);
+ return NULL;
+ }
+#endif
+
dia = e_dialog_new(NULL, "E", "_error_dialog");
if (!dia) return NULL;
e_dialog_title_set(dia, title);
diff --git a/src/tests/wayland/meson.build b/src/tests/wayland/meson.build
index 4579a5b27..190cffa51 100644
--- a/src/tests/wayland/meson.build
+++ b/src/tests/wayland/meson.build
@@ -99,6 +99,7 @@ wl_protocol_tests = [
['text-input', 'test_text_input.c'],
['input-method-keyboard', 'test_input_method_keyboard.c'],
['input-popup', 'test_input_popup.c'],
+ ['no-dialogs', 'test_no_dialogs.c'],
]
# Shared plumbing: registry binding, toplevel construction, enumeration and a
diff --git a/src/tests/wayland/test_no_dialogs.c b/src/tests/wayland/test_no_dialogs.c
new file mode 100644
index 000000000..3ccef67f0
--- /dev/null
+++ b/src/tests/wayland/test_no_dialogs.c
@@ -0,0 +1,103 @@
+/* A test session must never be shown a dialog.
+ *
+ * There is nobody to read one, and a window appearing unbidden takes the
+ * keyboard focus off whatever the test is driving. That is not a cosmetic
+ * problem: every assertion after it is about the wrong window, and the failure
+ * names something unrelated to the actual fault. It cost a run of the
+ * input-method tests before this existed - a dialog won the focus race and the
+ * test reported that its own window "did not take keyboard focus".
+ *
+ * E_TEST_NO_DIALOGS is the switch, set by run-nested.sh and by the wlcs
+ * driver. It used to be honoured at one call site, in e_system.c, which
+ * covered the one dialog somebody had been bitten by and nothing else. It is
+ * now honoured in e_util_dialog_internal, which every error dialog in E goes
+ * through - e_util_dialog_show is a macro over it.
+ *
+ * The trigger here is E's own window_focus action given a direction that does
+ * not exist. That path calls e_util_dialog_show with an "Invalid parameter"
+ * message, which makes it a real dialog raised by real compositor code rather
+ * than something invented for the test. Any other dialog would do; this one is
+ * reachable from wl_test.client_action, which is what makes it usable.
+ *
+ * The suppressed message is not lost - it goes to the compositor log, which
+ * run-nested.sh prints on failure. This test cannot check that from the client
+ * side, so it checks the part a client can see: no window.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_wl_testkit.h"
+
+#define PROG "test-no-dialogs"
+
+/* The name every error dialog is created with - e_dialog_new(NULL, "E",
+ * "_error_dialog") in e_util_dialog_internal - and what E reports as the
+ * window's app_id. */
+#define DIALOG_APP_ID "_error_dialog"
+
+static Tk_Client *
+_dialog_window(Tk *tk)
+{
+ static Tk_Client all[TK_MAX_CLIENTS];
+ int n, i;
+
+ n = tk_clients(tk, all, TK_MAX_CLIENTS);
+ for (i = 0; i < n; i++)
+ if (!strcmp(all[i].app_id, DIALOG_APP_ID)) return &all[i];
+ return NULL;
+}
+
+int
+main(void)
+{
+ Tk *tk;
+ Tk_Toplevel *top;
+ Tk_Client *c, *dia;
+ unsigned int id;
+ int i;
+
+ tk = tk_connect(PROG);
+
+ top = tk_toplevel_new(tk, "no-dialogs", "no dialogs", 200, 200);
+ tk_settle(tk);
+ c = tk_expect(tk, "no-dialogs");
+ id = c->id;
+
+ if (_dialog_window(tk))
+ tk_fail(tk, "a dialog was already on screen before this test did "
+ "anything - something raised one during startup, which is "
+ "the case E_TEST_NO_DIALOGS exists for");
+
+ /* Raise one, from compositor code, through the ordinary path. */
+ tk_action(tk, id, "window_focus", "no-such-direction");
+ tk_settle(tk);
+
+ /* Dialogs are built and shown from the main loop, so give it several
+ * iterations rather than one before concluding nothing appeared. */
+ for (i = 0; i < 10; i++)
+ {
+ dia = _dialog_window(tk);
+ if (dia)
+ tk_fail(tk, "an error dialog appeared (app_id '%s', title '%s', "
+ "%dx%d+%d+%d) with E_TEST_NO_DIALOGS set. It is honoured "
+ "in e_util_dialog_internal, which every dialog in E goes "
+ "through - if this one got past, it was built some other "
+ "way and that path needs the same guard",
+ dia->app_id, dia->title, dia->w, dia->h, dia->x, dia->y);
+ tk_sync(tk);
+ }
+
+ /* The harm a dialog does, checked directly: focus stays where the test put
+ * it. A dialog that appeared and did *not* take focus would still be wrong,
+ * but this is the property everything else depends on. */
+ c = tk_expect(tk, "no-dialogs");
+ if (!(c->states & WL_TEST_CLIENT_STATE_FOCUSED))
+ tk_fail(tk, "the test's own window lost focus after an action that would "
+ "have raised a dialog");
+
+ printf(PROG ": ok - no dialog, focus undisturbed\n");
+
+ tk_disconnect(tk);
+ return 0;
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.