Subject: Re: bug#78474: 31.0.50; Wrong char insertion in rxvt

From: Robert Pluim <[email-masked]>
Date: Mon, 21 Jul 2025 16:20:06 +0200

>>>>> On Mon, 21 Jul 2025 15:52:31 +0300, Eli Zaretskii <[email-masked]> said:

    >> From: Robert Pluim <[email-masked]>
    >> Cc: [email-masked],  [email-masked],  [email-masked],
    >> [email-masked]
    >> Date: Mon, 21 Jul 2025 14:12:54 +0200
    >> 
    >> >>>>> On Thu, 17 Jul 2025 08:30:44 +0300, Eli Zaretskii <[email-masked]> said:
    >> 
    Eli> Feel free to suggest a patch with such a variable.
    >> 
    >> See below. I have zero ego about the name of the option.

    Eli> See below.

    >> Perhaps the "stty -tabs" workaround should go into PROBLEMS.

    Eli> A good idea, but please add that to PROBLEMS on the release branch
    Eli> (unlike the rest of the patch).

Done

    Eli> We should also think how to make the accessibility-related knobs more
    Eli> discoverable.  Perhaps a new section in the user manual is in order.
    >> 
    >> Indeed, I didnʼt find a good place to put this. What else would go in
    >> this new node apart from this new user option? `text-scale-increase',
    >> I guess, and discussion of the high-contrast themes.

    Eli> Also w32-use-visible-system-caret (a link to the relevant appendix
    Eli> should be enough).  Hopefully, the list will grow.

OK, Iʼve put this on my list. Could we point at EmacsSpeak as well?

    >> (did anyone ever (re-)implement sticky modifier keys for Emacs? Thatʼs
    >> about the only thing I miss from XEmacs)

    Eli> Are there nowadays systems which don't have this built-in?

    >> +** New user option 'tty-allow-tabs-for-motion'.

    Eli> I suggest 'cursor-motion-use-tabs' instead.

Done. Patch attached, without any manual changes, for now.

Robert
-- 

>From 5101647f3c762f2155aa754d0499b962779478dc Mon Sep 17 00:00:00 2001
From: Robert Pluim <[email-masked]>
Date: Mon, 21 Jul 2025 16:13:41 +0200
Subject: [PATCH] Allow disabling use of TABS for motion on TTYs (Bug#78474)

* src/term.c (syms_of_term): New user option
'cursor-motion-use-tabs'.
* src/cm.c (calccost): Don't emit TAB for motion when
'cursor-motion-use-tabs' is false.
* lisp/cus-start.el (standard): Add custom spec for it.

* etc/NEWS: Announce the new user option.
---
 etc/NEWS          |  7 +++++++
 lisp/cus-start.el |  1 +
 src/cm.c          |  3 ++-
 src/term.c        | 11 +++++++++++
 4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index b469b22aacf..85d089bd126 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -85,6 +85,13 @@ the 'standard-display-table's extra slots with Unicode characters.
 Please see the documentation of that function to see which slots of the
 display table it changes.
 
+---
+** New user option 'cursor-motion-use-tabs'.
+The display optimization where TAB characters may be used to move around
+on a TTY frame can now be disabled by customizing the user option
+'cursor-motion-use-tabs' to nil (default t).  This is to accommodate
+screen readers which may interpret those TAB characters literally.
+
 +++
 ** Child frames are now supported on TTY frames.
 This supports use-cases like Posframe, Corfu, and child frames acting
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 3bc296e4ad1..d68113e27f7 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -602,6 +602,7 @@ minibuffer-prompt-properties--setter
 						    "21.1")
              ;; term.c
              (visible-cursor cursor boolean "22.1")
+             (cursor-motion-use-tabs cursor boolean "31.1")
              ;; terminal.c
              (ring-bell-function display
               (choice
diff --git a/src/cm.c b/src/cm.c
index 150d1c9a580..0eaa1c41337 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -225,7 +225,8 @@ calccost (struct tty_display_info *tty,
 	goto dodelta;		/* skip all the tab junk */
     }
     /* Tabs (the toughie) */
-    if (tty->Wcm->cc_tab >= BIG || !tty->Wcm->cm_usetabs)
+    if (!cursor_motion_use_tabs /* Bug#78474.  */
+	|| tty->Wcm->cc_tab >= BIG || !tty->Wcm->cm_usetabs)
 	goto olddelta;		/* forget it! */
 
     /*
diff --git a/src/term.c b/src/term.c
index 8aa47322d19..b6dbf100437 100644
--- a/src/term.c
+++ b/src/term.c
@@ -5167,6 +5167,17 @@ syms_of_term (void)
 trigger redisplay.  */);
   tty_menu_calls_mouse_position_function = 0;
 
+  DEFVAR_BOOL ("cursor-motion-use-tabs", cursor_motion_use_tabs,
+    doc: /* Whether TTY frames may use TAB characters for moving around.
+As a display optimization, Emacs may move between two positions on a TTY
+frame by emitting TAB characters, combined with TTY motion commands,
+when this is more efficient than using only motion commands.  These
+characters can interfere with the functioning of some software, such as
+screen readers, which interpret the TAB characters literally.  Set this
+to nil to disable this optimization, but be warned that this may affect
+redisplay performance.  */);
+  cursor_motion_use_tabs = 1;
+
   defsubr (&Stty_display_color_p);
   defsubr (&Stty_display_color_cells);
   defsubr (&Stty_no_underline);
-- 
2.39.5