Subject: bug#72331: 29.4; Modifying horizontal-scroll-bar does not fully work (MacOS only)

From: Gerd Möllmann <[email-masked]>
Date: Thu, 08 Aug 2024 08:45:31 +0200

Gerd Möllmann <[email-masked]> writes:

> Eli Zaretskii <[email-masked]> writes:
>
>>> Date: Sat, 27 Jul 2024 22:10:06 -0700
>>> From:  Jared Finder via "Bug reports for GNU Emacs,
>>>  the Swiss army knife of text editors" <[email-masked]>
>>> 
>>> Directly modifying the variable horizontal-scroll-bar on MacOS doesn't
>>> show a scroll bar unless the frame also has the horizontal-scroll-bars
>>> frame  parameter set.  This only happens on MacOS, on Linux and Windows
>>> everything behaves as I would expect.
>>> 
>>> To reproduce, define the following function:
>>> 
>>> (defun bug-report-toggle-buffer-horizontal-scroll-bar ()
>>>    "Like `toggle-scroll-bar', but for just the current buffer.
>>> And for horizontal scroll bars.  I guess it's acutally very
>>> different."
>>>    (interactive)
>>>    (setq horizontal-scroll-bar (if horizontal-scroll-bar nil 'bottom))
>>>    (set-window-buffer (selected-window) (current-buffer)))
>>> 
>>> Then run M-x bug-report-toggle-buffer-horizontal-scroll-bar repeatedly
>>> and observe that on MacOS space gets reserved for the horizontal scroll
>>> bar but no scroll bar is rendered.  Finally, run M-x
>>> horizontal-scroll-bar-mode and observe that now the horizontal scroll
>>> bar is properly shown and hidden.
>>> 
>>> I also tested this on master and observed the same behavior.
>>
>> Thanks.
>>
>> Could some macOS user please look into this?
>
> Same for vertical-scroll-bar, BTW. From reading the code and setting a
> breakpoint in ns_set_horizontal_scroll_bar, I'd say it's the definition
> of these macros in nsterm.h:
>
>   /* Compute pixel size for vertical scroll bars.  */
>   #define NS_SCROLL_BAR_WIDTH(f)						\
>     (FRAME_HAS_VERTICAL_SCROLL_BARS (f)					\
>      ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0			\
>              ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f)				\
>              : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)))	\
>      : 0)
>
>   /* Compute pixel size for horizontal scroll bars.  */
>   #define NS_SCROLL_BAR_HEIGHT(f)						\
>     (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)					\
>      ? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0			\
>              ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f)				\
>              : (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)))	\
>      : 0)
>
> Both check FRAME_HAS_H/V_SCROLL_BARS which in this case results in width
> or height being 0, which is a bit small.
>
> A change like the one below makes the horizontal scroll bar visible with
> Jared's test function.

I think the fix is the attached patch. Jared, could you please try it?

>From 0388af932e0c013ad45597fffad3e990ae00d664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gerd=20M=C3=B6llmann?= <[email-masked]>
Date: Thu, 8 Aug 2024 08:19:56 +0200
Subject: [PATCH] NS: Fix scroll-bar setting code ()bug#72331)

* src/nsterm.m (ns_set_vertical_scroll_bar): Use
WINDOW_SCROLL_AREA_WIDTH instead of NS_SCROLL_BAR_WIDTH.
(ns_set_horizontal_scroll_bar): Use WINDOW_SCROLL_AREA_HEIGHT
instead of NS_SCROLL_BAR_HEIGHT. Clear area differently if vertical
scroll bars are present.
* src/nsterm.h (NS_SCROLL_BAR_WIDTH, NS_SCROLL_BAR_HEIGHT): Remove.
---
 src/nsterm.h | 16 ----------------
 src/nsterm.m |  6 +++---
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/src/nsterm.h b/src/nsterm.h
index 844f2b2bc78..256a233558e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1070,22 +1070,6 @@ #define FRAME_TOOLBAR_HEIGHT(f)                                         \
                      styleMask:[[FRAME_NS_VIEW (f) window] styleMask]]) \
            - NSHeight([[[FRAME_NS_VIEW (f) window] contentView] frame])))
 
-/* Compute pixel size for vertical scroll bars.  */
-#define NS_SCROLL_BAR_WIDTH(f)						\
-  (FRAME_HAS_VERTICAL_SCROLL_BARS (f)					\
-   ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0			\
-	   ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f)				\
-	   : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)))	\
-   : 0)
-
-/* Compute pixel size for horizontal scroll bars.  */
-#define NS_SCROLL_BAR_HEIGHT(f)						\
-  (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)					\
-   ? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0			\
-	   ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f)				\
-	   : (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)))	\
-   : 0)
-
 /* Difference between char-column-calculated and actual SB widths.
    This is only a concern for rendering when SB on left.  */
 #define NS_SCROLL_BAR_ADJUST(w, f)				\
diff --git a/src/nsterm.m b/src/nsterm.m
index 594f7ba974b..4f2047fa3ef 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5072,7 +5072,7 @@ Function modeled after x_draw_glyph_string_box ().
   window_box (window, ANY_AREA, 0, &window_y, 0, &window_height);
   top = window_y;
   height = window_height;
-  width = NS_SCROLL_BAR_WIDTH (f);
+  width = WINDOW_SCROLL_BAR_AREA_WIDTH (window);
   left = WINDOW_SCROLL_BAR_AREA_X (window);
 
   r = NSMakeRect (left, top, width, height);
@@ -5166,7 +5166,7 @@ Function modeled after x_draw_glyph_string_box ().
   window_box (window, ANY_AREA, &window_x, 0, &window_width, 0);
   left = window_x;
   width = window_width;
-  height = NS_SCROLL_BAR_HEIGHT (f);
+  height = WINDOW_SCROLL_BAR_AREA_HEIGHT (window);
   top = WINDOW_SCROLL_BAR_AREA_Y (window);
 
   r = NSMakeRect (left, top, width, height);
@@ -5204,7 +5204,7 @@ Function modeled after x_draw_glyph_string_box ().
      it fills with junk.  */
   if (!NILP (window->vertical_scroll_bar))
     ns_clear_frame_area (f, WINDOW_SCROLL_BAR_AREA_X (window), top,
-                         NS_SCROLL_BAR_HEIGHT (f), height);
+                         WINDOW_SCROLL_BAR_AREA_WIDTH (window), height);
 
   if (update_p)
     [bar setPosition: position portion: portion whole: whole];
-- 
2.46.0