Subject: Re: bug#12419: Mouse click changes layout

From: martin rudalics <[email-masked]>
Date: Sun, 16 Sep 2012 19:45:42 +0200

> Ahem, not so sure what you'd want here.  But playing with your
 >
 >  >   emacs -Q
 >  >   (message (make-string 1000 ?a))
 >  >   C-x C-e
 >
 > example, which btw. give me only 8 lines, whit the initial quote out of
 > sight, you can easily reproduce this:
 >
 > Split *scratch* horizontally

... vertically (the new window is below the old one) ...

 > and then click on the 1 of 1000.

... in the new, lower window.

 > The
 > minibuffer shrinks, the 1 is blinking, but the mouse is no over the n of
 > notes, which slid down.  When letting go, the n blinks and all up to
 > before 1000 is marked.

I can see that.

 > Independently of resizing, something similar happens for sideways
 > scrolling:  Split *scratch* vertically, click on the v of visit,

What is the "v of visit"?

 > nothing
 > happens (that's where it dffers).  But then move the mouse 1 char right,
 > this triggers a sideways scroll.  The mouse is now over the e of file.
 > When letting go, it marks "visit that fil" but worse, it scrolls yet
 > again by the same amount, so that the mouse is now at the end of the
 > line, far from the text it marked.
 >
 > I'd expect both cases to consistently do something only when I release
 > the mouse, or when I drag to outside the window to force scrolling.

Can you try the attached patch?

Thanks, martin
=== modified file 'lisp/window.el'
--- lisp/window.el	2012-09-16 04:52:38 +0000
+++ lisp/window.el	2012-09-16 17:38:02 +0000
@@ -2394,27 +2394,32 @@
 This function is only called by the minibuffer window resizing
 routines.  It resizes windows proportionally and never deletes
 any windows."
-  (when (numberp delta)
-    (let (ignore)
-      (cond
-       ((< delta 0)
-	(setq delta (window-sizable window delta)))
-       ((> delta 0)
-	(unless (window-sizable window delta)
-	  (setq ignore t))))
-
-      (window--resize-reset (window-frame window))
-      ;; Ideally, we would resize just the last window in a combination
-      ;; but that's not feasible for the following reason: If we grow
-      ;; the minibuffer window and the last window cannot be shrunk any
-      ;; more, we shrink another window instead.  But if we then shrink
-      ;; the minibuffer window again, the last window might get enlarged
-      ;; and the state after shrinking is not the state before growing.
-      ;; So, in practice, we'd need a history variable to record how to
-      ;; proceed.  But I'm not sure how such a variable could work with
-      ;; repeated minibuffer window growing steps.
-      (window--resize-this-window window delta nil ignore t)
-      delta)))
+  (let (ignore)
+    (cond
+     ((not (numberp delta))
+      (setq delta 0))
+     ((zerop delta))
+     ((< delta 0)
+      (setq delta (window-sizable window delta))
+      (window--resize-reset (window-frame window))
+      ;; When shrinking the root window, emulate an edge drag in order
+      ;; to not resize other windows if we can avoid it (Bug#12419).
+      (window--resize-this-window
+       window delta nil ignore t 'before
+       (+ (window-top-line window) (window-total-size window)))
+      ;; Don't record new normal sizes to make sure that shrinking back
+      ;; proportionally works as intended.
+      (walk-window-tree
+       (lambda (window) (set-window-new-normal window 'ignore))))
+     ((> delta 0)
+      (window--resize-reset (window-frame window))
+      (unless (window-sizable window delta)
+	(setq ignore t))
+      ;; When growing the root window, resize proportionally.  This
+      ;; should give windows back their original sizes (hopefully).
+      (window--resize-this-window window delta nil ignore t)))
+     ;; Return the possibly adjusted DELTA.
+     delta))
 
 (defun adjust-window-trailing-edge (window delta &optional horizontal)
   "Move WINDOW's bottom edge by DELTA lines.