Subject: bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs

From: Juri Linkov <[email-masked]>
Date: Thu, 31 Oct 2019 01:59:38 +0200

>> I tried to not reset these flags only for the tab-line, and indeed
>> when the tab-line is truncated, then truncated_on_right_p is true
>> most of the time, but not always.  It's false when the tab-line
>> is truncated between tabs.
>> 
>> AFAIU by looking at 'display_string', it looks like this has something
>> to do with whitespace between tabs as this comment explains:
>> 
>> 	  /* Add truncation mark, but don't do it if the line is
>> 	     truncated at a padding space.  */
>
> I don't think this is the reason, because AFAICT tab-line-format
> doesn't include constructs that would pad its elements with spaces.
>
> Can you cook up a simple recipe where the truncation bitmaps don't
> appear, and also show the patch you used not to reset those flags?
> I'd like to look into what happens in the code in that case.

Please try with this patch to resize the frame right edge until the edge
is between tabs, then it outputs "truncated_on_right_p=0" whereas
when the truncating frame edge is not between tabs then it outputs
"truncated_on_right_p=1"

diff --git a/src/xdisp.c b/src/xdisp.c
index 987c760c74..b20c7718bd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1419,6 +1419,33 @@ window_hscroll_limited (struct window *w, struct frame *f)
   return window_hscroll;
 }
 
+static bool
+current_tab_visible_p (struct window *w, int *tab_num)
+{
+  bool visible_p = false;
+
+  if (window_wants_tab_line (w))
+    {
+      struct it it;
+
+      Lisp_Object window_tab_line_format
+	= window_parameter (w, Qtab_line_format);
+
+      w->tab_line_height
+	= display_mode_line (w, TAB_LINE_FACE_ID,
+			     NILP (window_tab_line_format)
+			     ? BVAR (current_buffer, tab_line_format)
+			     : window_tab_line_format);
+
+      init_iterator (&it, w, -1, -1, NULL, TAB_LINE_FACE_ID);
+
+      fprintf (stderr, "tab_line_p=%d truncated_on_right_p=%d last_visible_x=%d\n",
+               it.glyph_row->tab_line_p, it.glyph_row->truncated_on_right_p, it.last_visible_x);
+    }
+
+  return visible_p;
+}
+
 /* Return true if position CHARPOS is visible in window W.
    CHARPOS < 0 means return info about WINDOW_END position.
    If visible, set *X and *Y to pixel coordinates of top left corner.
@@ -24897,6 +24924,13 @@ display_mode_lines (struct window *w)
 
   if (window_wants_tab_line (w))
     {
+      int tab_num = 0;
+
+      if (current_tab_visible_p (w, &tab_num))
+        {
+          /* Set some Lisp variable */
+        }
+
       Lisp_Object window_tab_line_format
 	= window_parameter (w, Qtab_line_format);
 
@@ -24984,7 +25018,10 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
   it.glyph_row->full_width_p = true;
   it.glyph_row->continued_p = false;
   it.glyph_row->truncated_on_left_p = false;
-  it.glyph_row->truncated_on_right_p = false;
+
+  /* Currently only tab-line needs truncation detection.  */
+  if (face_id != TAB_LINE_FACE_ID)
+    it.glyph_row->truncated_on_right_p = false;
 
   /* Make a 3D mode-line have a shadow at its right end.  */
   face = FACE_FROM_ID (it.f, face_id);