Subject: Re: bug#76084: 31.0.50; Dragging tab line does not resize windows, unlike header line or mode line

From: Jared Finder <[email-masked]>
Date: Sat, 22 Feb 2025 14:38:59 -0800

On 2025-02-10 02:15, martin rudalics wrote:
>> To handle this I would need to add checks against the down-mouse-1
>> keybinding before setting the mouse icon.  I'm just worried about
>> performance here since looking up the keymap would get run on mouse
>> motion.
> 
> I think there's no reason to bother about 'ruler-mode'.  IIRC, apart
> from the scroll bar, the ruler has no "empty space" and dragging should
> mostly happen in a horizontal fashion.

Attached is a patch that adds the vertical scroll icon for header and 
tab lines.  I also altered ruler-mode so that dragging works with it as 
well as it has no real reason to block dragging AFAICT.  Similar changes 
would be needed in other packages if the desire is to be aligned with 
the newly shown drag icon.  The only way to outright hide the drag icon 
is to add a keymap via text properties, which is already the case for 
the mode line.  If this (small) breakage seems acceptable, then I think 
this is strictly better.

The alternative here is to add a call to Fkey_binding in 
note_line_or_margin_highlight to check what the down-mouse-1 binding is. 
  Let me know if that is more appropriate.  I'm just nervous because 
there are comments about Fkey_binding maybe causing GC and in general is 
seems much more heavyweight an operation for each mouse move.

   -- MJF

From b81f0946fd68f8d859a09b4746a5f8116e852df4 Mon Sep 17 00:00:00 2001
From: Jared Finder <[email-masked]>
Date: Sat, 22 Feb 2025 14:25:37 -0800
Subject: [PATCH] Show drag cursor on all window lines (mode, tab, header)

* lisp/ruler-mode.el (ruler-mode-map): Remove down-mouse-1
binding that conflicts with dragging header line.
* src/xdisp.c (note_mode_line_or_margin_highlight): Renamed
to...
(note_line_or_margin_highlight): ...new name since it applies to
any window line (mode, tab, header).  Set drag cursor for window
top lines.
(note_mouse_highlight): Update call to new name.
---
 lisp/ruler-mode.el |  1 -
 src/xdisp.c        | 33 +++++++++++++++++++--------------
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el
index 64568e06cc9..e196722a413 100644
--- a/lisp/ruler-mode.el
+++ b/lisp/ruler-mode.el
@@ -511,7 +511,6 @@ ruler-mode-toggle-show-tab-stops
 
 (defvar-keymap ruler-mode-map
   :doc "Keymap for `ruler-mode'."
-  "<header-line> <down-mouse-1>"   #'ignore
   "<header-line> <down-mouse-3>"   #'ignore
   "<header-line> <down-mouse-2>"   #'ruler-mode-mouse-grab-any-column
   "<header-line> S-<down-mouse-1>" #'ruler-mode-mouse-set-left-margin
diff --git a/src/xdisp.c b/src/xdisp.c
index 0de5aee86dd..982f7a4d5d2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -35605,15 +35605,15 @@ define_frame_cursor1 (struct frame *f, Emacs_Cursor cursor, Lisp_Object pointer)
 #endif
 }
 
-/* Take proper action when mouse has moved to the mode or header line
-   or marginal area AREA of window W, x-position X and y-position Y.
-   X is relative to the start of the text display area of W, so the
-   width of bitmap areas and scroll bars must be subtracted to get a
-   position relative to the start of the mode line.  */
+/* Take proper action when mouse has moved to one of the window's lines
+   (mode, tab, or header) or marginal area AREA of window W, x-position
+   X and y-position Y.  X is relative to the start of the text display
+   area of W, so the width of bitmap areas and scroll bars must be
+   subtracted to get a position relative to the start of a line.  */
 
 static void
-note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
-				    enum window_part area)
+note_line_or_margin_highlight (Lisp_Object window, int x, int y,
+			       enum window_part area)
 {
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
@@ -35749,9 +35749,13 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
       /* Change the mouse pointer according to what is under it.  */
       if (FRAME_WINDOW_P (f))
 	{
-	  bool draggable = (! WINDOW_BOTTOMMOST_P (w)
-			    || minibuf_level
-			    || NILP (Vresize_mini_windows));
+	  bool draggable_window_bottom_line =
+	    (area == ON_MODE_LINE && (! WINDOW_BOTTOMMOST_P (w)
+				      || minibuf_level
+				      || NILP (Vresize_mini_windows)));
+	  bool draggable_window_top_line =
+	    ((area == ON_HEADER_LINE || area == ON_TAB_LINE)
+	     && ! WINDOW_TOPMOST_P (w));
 
 	  if (STRINGP (string))
 	    {
@@ -35770,11 +35774,12 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 		  map = Fget_text_property (pos, Qlocal_map, string);
 		  if (!KEYMAPP (map))
 		    map = Fget_text_property (pos, Qkeymap, string);
-		  if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
+		  if (!KEYMAPP (map) && (draggable_window_top_line
+					 || draggable_window_bottom_line))
 		    cursor = FRAME_OUTPUT_DATA (f)->vertical_drag_cursor;
 		}
 	    }
-	  else if (draggable && area == ON_MODE_LINE)
+	  else if (draggable_window_top_line || draggable_window_bottom_line)
 	    cursor = FRAME_OUTPUT_DATA (f)->vertical_drag_cursor;
 	  else if ((area == ON_MODE_LINE
 		    && WINDOW_BOTTOMMOST_P (w)
@@ -36206,11 +36211,11 @@ note_mouse_highlight (struct frame *f, int x, int y)
     }
 #endif
 
-  /* Mouse is on the mode, header line or margin?  */
+  /* Mouse is on a line or margin?  */
   if (part == ON_MODE_LINE || part == ON_HEADER_LINE || part == ON_TAB_LINE
       || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
     {
-      note_mode_line_or_margin_highlight (window, x, y, part);
+      note_line_or_margin_highlight (window, x, y, part);
 
 #ifdef HAVE_WINDOW_SYSTEM
       if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
-- 
2.39.5