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

From: Eli Zaretskii <[email-masked]>
Date: Thu, 31 Oct 2019 16:25:21 +0200

> From: Juri Linkov <[email-masked]>
> Cc: [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"

We've been miscommunicating.  Sorry, it's my fault: I didn't look
closely enough at the code you wrote in tab-line.el, and built me a
mental model that is completely wrong.

> +      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);

Calling init_iterator _after_ performing display has no useful effect
on anything.  And since the 'struct it' you pass to it is unrelated to
what display_mode_line used, the value you print has no relation to
what happens inside display_mode_line, nor with the actual flags of
the glyph row produced by display_mode_line for displaying the
tab-line.  I verified in the debugger that when the tab-line is longer
than the window width, the truncated_on_right_p flag of the tab-line's
glyph row is always set, no matter how I resize the frame.

(Given what I write below, this is not really important; I just wanted
to point out your mistakes for the future.)

> @@ -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;

Here's the thing: I thought that you wanted the truncation indications
to be displayed on the fringes, like we do with text-area lines.  This
is why I started talking about truncated_on_right_p flag: this flag is
used by fringe.c to decide where to display the truncation bitmaps.

But tab-line.el handles the hscrolling and truncation of tab-lines
entirely in Lisp, and displays the hscrolling arrows by itself.  So
you don't need the truncated_on_right_p flag at all, and might as well
revert the above change -- it has no effect for tab-line display the
way that you implemented it.

I now understand that you thought you needed this flag for finding the
current tab, and only for that.  I'm not yet sure that is true, see my
other message.  If it turns out I'm wrong, we can then return to this
issue and discuss whether and how you need to cause this flag to be
set.