This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository terminology.

View the commit online.

commit 3b3c0a311b24ce9aae7139eafaa932277987c7dc
Author: Boris Faure <[email protected]>
AuthorDate: Mon Sep 7 20:45:38 2026 +0200

    termpty: add tests on mode 2026
---
 src/bin/termpty.c    | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/tytest.c     |   3 +
 src/bin/unit_tests.h |   3 +
 3 files changed, 162 insertions(+)

diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 259db2ff..8c915da8 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -2076,4 +2076,160 @@ tytest_sync_soft_reset(void)
    return 0;
 }
 
+/* Change-callback coalescing (mode 2026)
+ * termio's _smart_pty_change() drops pty change callbacks while
+ * sync_output.active is true, so the whole render pipeline depends on
+ * _sync_output_end() firing cb.change.func exactly once when the window
+ * closes: on ESU, on the watchdog, or on an alt-buffer switch.
+ * _ty_feed() calls termpty_handle_buf() directly, bypassing the fire in
+ * termpty_read_cb(), so the counter below sees the sync path and nothing
+ * else. */
+
+/* Counts the number of times the change callback fires. */
+static void
+_ty_change_cb_count(void *data)
+{
+   int *fires = data;
+
+   (*fires)++;
+}
+
+/* Counts and stops the main loop so the watchdog test need not wait. */
+static void
+_ty_change_cb_count_quit(void *data)
+{
+   int *fires = data;
+
+   (*fires)++;
+   ecore_main_loop_quit();
+}
+
+/* safety timer for the watchdog test */
+static Eina_Bool
+_ty_loop_timeout_cb(void *data)
+{
+   Ecore_Timer **timer = data;
+
+   *timer = NULL; /* timer owns itself once it has fired */
+   ecore_main_loop_quit();
+   return ECORE_CALLBACK_CANCEL;
+}
+
+/* Test 6: One coalesced frame per BSU/ESU pair.
+ * No change callback may fire between BSU and ESU, however many writes the
+ * burst contains; ESU queues exactly one. */
+int
+tytest_sync_change_cb_coalesced(void)
+{
+   Termpty ty;
+   int fires = 0;
+
+   _ty_test_init(&ty, 80, 24);
+   ty.cb.change.func = _ty_change_cb_count;
+   ty.cb.change.data = ""
+
+   /* ESU with no window open has nothing to render. */
+   _ty_feed(&ty, "\x1b[?2026l");
+   assert(fires == 0);
+
+   _ty_feed(&ty, "\x1b[?2026h");
+   assert(ty.sync_output.active == EINA_TRUE);
+   assert(fires == 0);
+
+   /* A burst of full-line clears and rewrites: the pattern some TUIs
+    * emit.  Every one of these mutates the live screen; none may queue a
+    * frame. */
+   _ty_feed(&ty, "\r\x1b[2Kfoo\r\x1b[2Kbar\r\x1b[2Kbaz");
+   assert(fires == 0);
+
+   /* Nested BSU only pushes the watchdog deadline back. */
+   _ty_feed(&ty, "\x1b[?2026h");
+   assert(ty.sync_output.active == EINA_TRUE);
+   assert(fires == 0);
+
+   /* ESU closes the window and queues the single coalesced frame. */
+   _ty_feed(&ty, "\x1b[?2026l");
+   assert(ty.sync_output.active == EINA_FALSE);
+   assert(fires == 1);
+   assert(_ty_cell_cp(&ty, 0, 0) == 'b'); /* last write of the burst */
+
+   /* A second ESU has no window to close: no extra frame. */
+   _ty_feed(&ty, "\x1b[?2026l");
+   assert(fires == 1);
+
+   _ty_test_shutdown(&ty);
+   return 0;
+}
+
+/* Test 7: The watchdog queues the frame when ESU never arrives.
+ * Without this, a buggy or killed app would leave the window open and
+ * _smart_pty_change() would keep dropping frames forever. */
+int
+tytest_sync_change_cb_watchdog(void)
+{
+   Termpty ty;
+   int fires = 0;
+   Ecore_Timer *safety;
+
+   _ty_test_init(&ty, 80, 24);
+   ty.cb.change.func = _ty_change_cb_count_quit;
+   ty.cb.change.data = ""
+
+   _ty_feed(&ty, "\x1b[?2026h");
+   _ty_feed(&ty, "\r\x1b[2Kpartial");
+   assert(ty.sync_output.active == EINA_TRUE);
+   assert(ty.sync_output.watchdog != NULL);
+   assert(fires == 0);
+
+   /* No ESU is ever sent.  The 150ms watchdog has to end the window on its
+    * own; the safety timer only keeps a broken watchdog from hanging the
+    * suite. */
+   safety = ecore_timer_add(5.0, _ty_loop_timeout_cb, &safety);
+   ecore_main_loop_begin();
+   if (safety) ecore_timer_del(safety);
+
+   assert(fires == 1);
+   assert(ty.sync_output.active == EINA_FALSE);
+   assert(ty.sync_output.watchdog == NULL);
+   assert(ty.sync_output.shadow_rows == NULL);
+   /* The frame that got queued shows the live, partial burst. */
+   assert(_ty_cell_cp(&ty, 0, 0) == 'p');
+
+   _ty_test_shutdown(&ty);
+   return 0;
+}
+
+/* Test 8: An alt-buffer switch mid-sync queues one frame.
+ * The window is invalidated (the app is expected to re-bracket), and the
+ * renderer must be told, or the swapped-in screen never gets painted. */
+int
+tytest_sync_change_cb_altscreen(void)
+{
+   Termpty ty;
+   int fires = 0;
+
+   _ty_test_init(&ty, 80, 24);
+   ty.cb.change.func = _ty_change_cb_count;
+   ty.cb.change.data = ""
+
+   _ty_feed(&ty, "\x1b[?2026h");
+   _ty_feed(&ty, "\r\x1b[2Kmain");
+   assert(ty.sync_output.active == EINA_TRUE);
+   assert(fires == 0);
+
+   /* DECSET 1049 -- switch to the alternate buffer. */
+   _ty_feed(&ty, "\x1b[?1049h");
+   assert(ty.sync_output.active == EINA_FALSE);
+   assert(ty.sync_output.shadow_rows == NULL);
+   assert(fires == 1);
+
+   /* Back to the normal buffer with no window open: no frame from the sync
+    * path. */
+   _ty_feed(&ty, "\x1b[?1049l");
+   assert(fires == 1);
+
+   _ty_test_shutdown(&ty);
+   return 0;
+}
+
 #endif /* BINARY_TYFUZZ || BINARY_TYTEST */
diff --git a/src/bin/tytest.c b/src/bin/tytest.c
index 45e07c0d..338fe3d0 100644
--- a/src/bin/tytest.c
+++ b/src/bin/tytest.c
@@ -52,6 +52,9 @@ static struct {
        { "sync_nested", tytest_sync_nested},
        { "sync_resize", tytest_sync_resize},
        { "sync_soft_reset", tytest_sync_soft_reset},
+       { "sync_change_cb_coalesced", tytest_sync_change_cb_coalesced},
+       { "sync_change_cb_watchdog", tytest_sync_change_cb_watchdog},
+       { "sync_change_cb_altscreen", tytest_sync_change_cb_altscreen},
        { "percent_decode", tytest_percent_decode},
        { NULL, NULL},
 };
diff --git a/src/bin/unit_tests.h b/src/bin/unit_tests.h
index 6fb2e532..b5deeb24 100644
--- a/src/bin/unit_tests.h
+++ b/src/bin/unit_tests.h
@@ -26,6 +26,9 @@ int tytest_sync_watchdog_teardown(void);
 int tytest_sync_nested(void);
 int tytest_sync_resize(void);
 int tytest_sync_soft_reset(void);
+int tytest_sync_change_cb_coalesced(void);
+int tytest_sync_change_cb_watchdog(void);
+int tytest_sync_change_cb_altscreen(void);
 int tytest_percent_decode(void);
 
 #endif

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to