Subject: bug#16383: balance-windows fails in Emacs 24.3.50.1

From: martin rudalics <[email-masked]>
Date: Sat, 11 Jan 2014 11:25:18 +0100

> I applied the changes manually with no luck.

I suppose you applied the changes but did not recompile/evaluate
window.el afterwards.  Even if you did, the changes won't be picked up
when you restart Emacs because you did not change the corresponding part
of the executable (you would have to "make" Emacs for that purpose).

So simply take the patched code of `balance-windows-2' (for example, as
it is at the end of this mail), add it to your .emacs, and run it until
...

 > The Debian snapshot will
 > be updated soon, I hope.

... this happens.

 > Thank you for letting me know it's fixed... that gives me something to
 > look forward to. :)

Don't look forward, try now ;-)

Thanks, martin

(defun balance-windows-2 (window horizontal)
   "Subroutine of `balance-windows-1'.
WINDOW must be a vertical combination (horizontal if HORIZONTAL
is non-nil)."
   (let* ((char-size (if window-resize-pixelwise
			1
		      (frame-char-size window horizontal)))
	 (first (window-child window))
	 (sub first)
	 (number-of-children 0)
	 (parent-size (window-new-pixel window))
	 (total-sum parent-size)
	 failed size sub-total sub-delta sub-amount rest)
     (while sub
       (setq number-of-children (1+ number-of-children))
       (when (window-size-fixed-p sub horizontal)
	(setq total-sum
	      (- total-sum (window-size sub horizontal t)))
	(set-window-new-normal sub 'ignore))
       (setq sub (window-right sub)))

     (setq failed t)
     (while (and failed (> number-of-children 0))
       (setq size (/ total-sum number-of-children))
       (setq failed nil)
       (setq sub first)
       (while (and sub (not failed))
	;; Ignore child windows that should be ignored or are stuck.
	(unless (window--resize-child-windows-skip-p sub)
	  (setq sub-total (window-size sub horizontal t))
	  (setq sub-delta (- size sub-total))
	  (setq sub-amount
		(window-sizable sub sub-delta horizontal nil t))
	  ;; Register the new total size for this child window.
	  (set-window-new-pixel sub (+ sub-total sub-amount))
	  (unless (= sub-amount sub-delta)
	    (setq total-sum (- total-sum sub-total sub-amount))
	    (setq number-of-children (1- number-of-children))
	    ;; We failed and need a new round.
	    (setq failed t)
	    (set-window-new-normal sub 'skip)))
	(setq sub (window-right sub))))

     ;; How can we be sure that `number-of-children' is NOT zero here ?
     (setq rest (% total-sum number-of-children))
     ;; Fix rounding by trying to enlarge non-stuck windows by one line
     ;; (column) until `rest' is zero.
     (setq sub first)
     (while (and sub (> rest 0))
       (unless (window--resize-child-windows-skip-p window)
	(set-window-new-pixel sub (min rest char-size) t)
	(setq rest (- rest char-size)))
       (setq sub (window-right sub)))

     ;; Fix rounding by trying to enlarge stuck windows by one line
     ;; (column) until `rest' equals zero.
     (setq sub first)
     (while (and sub (> rest 0))
       (unless (eq (window-new-normal sub) 'ignore)
	(set-window-new-pixel sub (min rest char-size) t)
	(setq rest (- rest char-size)))
       (setq sub (window-right sub)))

     (setq sub first)
     (while sub
       ;; Record new normal sizes.
       (set-window-new-normal
        sub (/ (if (eq (window-new-normal sub) 'ignore)
		  (window-size sub horizontal t)
		(window-new-pixel sub))
	      (float parent-size)))
       ;; Recursively balance each window's child windows.
       (balance-windows-1 sub horizontal)
       (setq sub (window-right sub)))))