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

git pushed a commit to branch tymux
in repository terminology.

View the commit online.

commit 2c9d8e89b59e6d74c638be3924f548bd8b79bd92
Author: [email protected] <[email protected]>
AuthorDate: Mon May 4 18:56:59 2026 -0600

    fix(tymux): propagate Synchronized Output (2026) through daemon-proxy pipe
    
    Upstream commit 1a636d01 added support for DECSET/DECRST 2026
    (Synchronized Output, BSU/ESU) to preserve application-level frame
    intent. The tymux daemon was bypassing this: it would emit intermediate
    frames mid-application-frame, defeating the atomic-frame guarantee that
    tymux clients depend on.
    
    This change gates frame emission at both layers:
    
    termd_tymux.c (daemon-side gate): _pty_change_cb now early-returns when
    sync_output.active is true, holding off NOTIFY while the application is
    mid-frame. ESU, watchdog, soft-reset, and explicit resize will fire
    cb.change again with active=FALSE, at which point the animator is armed
    and exactly one frame ships. The TSRV_MSG_RESIZE handler now explicitly
    cancels any pending animator and calls _tymux_flush_and_notify after
    termpty_resize (which clears sync without firing cb.change), mirroring
    the behaviour of _pty_exit_cb.
    
    tymux.c (proxy-side wrapper): _render_screen wraps each per-NOTIFY
    repaint in BSU/ESU (\x1b[?2026h...l) so the outer host terminal flips
    the proxy's clear+content as one atomic frame. Outer terminals without
    2026 support ignore the sequences harmlessly.
    
    The two layers are complementary: the daemon gate preserves
    application-level frame intent across the tymux wire; the proxy wrapper
    avoids cosmetic glyph tearing from the proxy's multi-write emit on the
    host. Neither subsumes the other. Zero behaviour change for apps that
    never send 2026, or for non-tymux Terminology sessions.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
---
 src/bin/termd_tymux.c | 23 ++++++++++++++++++++---
 src/bin/tymux.c       |  8 ++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/bin/termd_tymux.c b/src/bin/termd_tymux.c
index f60d5ef2..b2ca1b81 100644
--- a/src/bin/termd_tymux.c
+++ b/src/bin/termd_tymux.c
@@ -413,6 +413,11 @@ _pty_change_cb(void *data)
    TermDTymux *sess = data;
 
    sess->dirty = EINA_TRUE;
+   /* While the application is mid-frame (BSU active), hold off NOTIFY.
+    * ESU (or the watchdog / soft-reset / resize) will fire cb.change again
+    * with active == EINA_FALSE, at which point the animator is armed and
+    * exactly one frame is shipped. */
+   if (sess->pty->sync_output.active) return;
    if (!sess->notify_anim)
      sess->notify_anim = ecore_animator_add(_tymux_notify_anim_cb, sess);
 }
@@ -507,10 +512,22 @@ _cb_client_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
               if (cols > 0 && rows > 0 &&
                   cols <= TERMSRV_MAX_COLS && rows <= TERMSRV_MAX_ROWS)
                 {
-                   /* termpty_resize triggers _pty_change_cb which flushes
-                    * to shm and sends NOTIFY to all clients — no explicit
-                    * _flush_screen_to_shm call needed here. */
+                   /* termpty_resize calls termpty_sync_output_reset, which
+                    * clears sync_output.active but does NOT fire cb.change.
+                    * With the sync gate in _pty_change_cb the old comment
+                    * (resize triggers change-cb → flush) is no longer
+                    * reliable: if active was TRUE before the resize the
+                    * animator was never armed.  Cancel any stale animator
+                    * and flush explicitly so clients get the new dimensions
+                    * immediately, matching the behaviour of _pty_exit_cb. */
                    termpty_resize(sess->pty, (int)cols, (int)rows);
+                   if (sess->notify_anim)
+                     {
+                        ecore_animator_del(sess->notify_anim);
+                        sess->notify_anim = NULL;
+                     }
+                   sess->dirty = EINA_FALSE;
+                   _tymux_flush_and_notify(sess);
                 }
            }
          break;
diff --git a/src/bin/tymux.c b/src/bin/tymux.c
index 5086c86a..e2b6fba4 100644
--- a/src/bin/tymux.c
+++ b/src/bin/tymux.c
@@ -843,6 +843,12 @@ _render_screen(const void *shm,
         *prev_rows_io  = srows;
      }
 
+   /* Wrap the entire repaint in BSU/ESU so the outer terminal flips the
+    * delta (or full repaint + clear) as one atomic frame.  The 2J clear is
+    * inside the window so that clear+content land together.  Outer terminals
+    * that do not support DECSET 2026 ignore these sequences harmlessly. */
+   write(STDOUT_FILENO, "\x1b[?2026h", 8);
+
    if (dim_changed)
      {
         /* Clear screen before full repaint on resize */
@@ -853,6 +859,8 @@ _render_screen(const void *shm,
      {
         _render_delta(shm, *prev_cells_io, scols, srows);
      }
+
+   write(STDOUT_FILENO, "\x1b[?2026l", 8);
 }
 
 /* ── commands ────────────────────────────────────────────────────────── */

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

Reply via email to