Subject: Re: bug#79351: 30.2; window-resize-symbollwise

From: martin rudalics <[email-masked]>
Date: Wed, 3 Sep 2025 09:38:49 +0200

> Tested with the latest stable Emacs.  Really like that behaviour,
 > didn't notice thank you!

It's still not as smooth as I want it.  The basic idea is to keep the
mode line as close to the mouse cursor as possible.  This is problematic
since the mouse is usually dragged with constant speed while the mode
line jumps (we could have it snap back at the end of dragging but that's
an annoying effect I'd like to avoid).  And it's particularly tricky
when a user reverts the dragging direction after overshooting.

One aspect the previous patch did not handle was the residue that
results when you have, for example, a character height of 22 pixels and
a mouse move of 18 or 40 pixels gets reported.  In that case I now have
the remaining 18 pixels be handled in the next move.  The results look
better here, please try the attached patch.

 > However looks like there's another issue unrelated to the window
 > splitting: for some reason, during frame resize, despite it going
 > line-by-line, the window afterwards is slightly cutted and has
 > slightly less than a whole number height.

You mean to say that a new frame has entire lines and the effect gets
visible only after resizing?  In either case, please file a new bug
report with the screenshot included.  In addition we would have to know:

- The build details as for a standard bug report (Emacs version, toolkit
   and so on).

- The window manager you use.

- The frame geometry in the bad state.  For this purpose do

   M-: (window--dump-frame)

   in that state.  This should get you a buffer *window--dump-frame*
   whose contents might tell what went wrong.

Thanks, martin

diff --git a/lisp/mouse.el b/lisp/mouse.el
index 907a4883230..903b386c658 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -855,20 +855,27 @@ mouse-drag-line
 	 ;; previously sampled position.  The difference of `position'
 	 ;; and `last-position' determines the size change of WINDOW.
 	 (last-position position)
-	 posn-window growth dragged)
+	 char-size posn-window growth residue dragged)
     ;; Decide on whether we are allowed to track at all and whose
     ;; window's edge we drag.
     (cond
      ((memq line '(header tab))
       ;; Drag bottom edge of window above the header line.
-      (setq window (window-in-direction 'above window t)))
-     ((eq line 'mode))
+      (setq window (window-in-direction 'above window t))
+      (unless window-resize-pixelwise
+	(setq char-size (frame-char-height frame))))
+     ((eq line 'mode)
+      (unless window-resize-pixelwise
+	(setq char-size (frame-char-height frame))))
      ((eq line 'vertical)
       (let ((divider-width (frame-right-divider-width frame)))
         (when (and (or (not (numberp divider-width))
                        (zerop divider-width))
                    (eq (frame-parameter frame 'vertical-scroll-bars) 'left))
-          (setq window (window-in-direction 'left window t))))))
+          (setq window (window-in-direction 'left window t))))
+      (unless window-resize-pixelwise
+	(setq char-size (frame-char-width frame)))))
+
     (let* ((exitfun nil)
            (move
 	    (lambda (event) (interactive "e")
@@ -905,8 +912,15 @@ mouse-drag-line
 				 (> position (+ (window-pixel-left window)
 						(window-pixel-width window)))))
 		  (setq dragged t)
-		  (adjust-window-trailing-edge window growth t t))
-		(setq last-position position))
+		  (unless window-resize-pixelwise
+		    (setq residue (% growth char-size))
+		    (setq growth (/ growth char-size)))
+		  (unless (zerop growth)
+		    (adjust-window-trailing-edge
+		     window growth t window-resize-pixelwise))
+		  (if window-resize-pixelwise
+		      (setq last-position position)
+		    (setq last-position (- position residue)))))
 	       (t
 		;; Drag bottom edge of `window'.
 		(setq start (event-start event))
@@ -936,8 +950,15 @@ mouse-drag-line
 				 (> position (+ (window-pixel-top window)
 						(window-pixel-height window)))))
 		  (setq dragged t)
-		  (adjust-window-trailing-edge window growth nil t))
-		(setq last-position position)))))
+		  (unless window-resize-pixelwise
+		    (setq residue (% growth char-size))
+		    (setq growth (/ growth char-size)))
+		  (unless (zerop growth)
+		    (adjust-window-trailing-edge
+		     window growth nil window-resize-pixelwise))
+		  (if window-resize-pixelwise
+		      (setq last-position position)
+		    (setq last-position (- position residue))))))))
            (old-track-mouse track-mouse))
       ;; Start tracking.  The special value 'dragging' signals the
       ;; display engine to freeze the mouse pointer shape for as long