Subject: bug#38181: Actual height of mode-line not taken into account

From: martin rudalics <[email-masked]>
Date: Mon, 18 Oct 2021 11:34:30 +0200

> By looking at these functions you could derive a new one
 > that calculates mode line heights in a similar way and peruse the return
 > values of that function in 'window-text-pixel-size' in the hope that
 > they won't change with the next redisplay.  The 'mode-lines' argument of
 > 'window-text-pixel-size' should then accept a value like 'update' to
 > reflect this special use case.  It might be worth the experience.

Or try the attached patch on master.  It seems to fix the issue here.

martin
diff --git a/src/xdisp.c b/src/xdisp.c
index 783ef396a3..ad833d99e3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10847,17 +10847,45 @@ DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_siz
   if (y > max_y)
     y = max_y;

-  if (EQ (mode_lines, Qtab_line) || EQ (mode_lines, Qt))
-    /* Re-add height of tab-line as requested.  */
-    y = y + WINDOW_TAB_LINE_HEIGHT (w);
+  if ((EQ (mode_lines, Qtab_line)
+       || EQ (mode_lines, Qt))
+      && window_wants_tab_line (w))
+    /* Add height of tab-line as requested.  */
+    {
+      Lisp_Object window_tab_line_format
+	= window_parameter (w, Qtab_line_format);
+
+      y = y + display_mode_line (w, TAB_LINE_FACE_ID,
+				 NILP (window_tab_line_format)
+				 ? BVAR (current_buffer, tab_line_format)
+				 : window_tab_line_format);
+    }

-  if (EQ (mode_lines, Qheader_line) || EQ (mode_lines, Qt))
-    /* Re-add height of header-line as requested.  */
-    y = y + WINDOW_HEADER_LINE_HEIGHT (w);
+  if ((EQ (mode_lines, Qheader_line)
+       || EQ (mode_lines, Qt))
+      && window_wants_header_line (w))
+    {
+      Lisp_Object window_header_line_format
+	= window_parameter (w, Qheader_line_format);

-  if (EQ (mode_lines, Qmode_line) || EQ (mode_lines, Qt))
-    /* Add height of mode-line as requested.  */
-    y = y + WINDOW_MODE_LINE_HEIGHT (w);
+      y = y + display_mode_line (w, HEADER_LINE_FACE_ID,
+				 NILP (window_header_line_format)
+				 ? BVAR (current_buffer, header_line_format)
+				 : window_header_line_format);
+    }
+
+  if ((EQ (mode_lines, Qmode_line)
+       || EQ (mode_lines, Qt))
+      && window_wants_mode_line (w))
+    {
+      Lisp_Object window_mode_line_format
+	= window_parameter (w, Qmode_line_format);
+
+      y = y + display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
+				 NILP (window_mode_line_format)
+				 ? BVAR (current_buffer, mode_line_format)
+				 : window_mode_line_format);
+    }

   bidi_unshelve_cache (itdata, false);