From xemacs-m  Tue May  6 11:22:09 1997
Received: from crystal.WonderWorks.COM (crystal.WonderWorks.com [192.203.206.1])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id LAA09127
	for <xemacs-beta@xemacs.org>; Tue, 6 May 1997 11:22:06 -0500 (CDT)
Received: by crystal.WonderWorks.COM 
	id QQcojp26367; Tue, 6 May 1997 12:22:06 -0400 (EDT)
Date: Tue, 6 May 1997 12:22:06 -0400 (EDT)
Message-Id: <QQcojp26367.199705061622@crystal.WonderWorks.COM>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
From: Kyle Jones <kyle_jones@wonderworks.com>
To: xemacs-beta@xemacs.org
Subject: Re: can't drag bottommost modeline 
In-Reply-To: <199705060554.WAA25493@carnifex.cogit.com>
References: <199705052049.NAA23697@carnifex.cogit.com>
	<QQcogz12348.199705052317@crystal.WonderWorks.COM>
	<QQcohv16525.199705060459@crystal.WonderWorks.COM>
	<199705060554.WAA25493@carnifex.cogit.com>
X-Mailer: VM 6.31 under 20.2 XEmacs Lucid (beta4)
X-Face: /cA45WHG7jWq>(O3&Z57Y<"WsX5ddc,4c#w0F*zrV#=M
        0@~@,s;b,aMtR5Sqs"+nU.z^CSFQ9t`z2>W,S,]:[+2^
        Nbf6v4g>!&,7R4Ot4Wg{&tm=WX7P["9%a)_da48-^tGy
        ,qz]Z,Zz\{E.,]'EO+F)@$KtF&V

Chris Dean writes:
 > I think there's an off by one bug somewhere in here.  If
 > you drag any modeline (not just the one directly above the
 > minibuffer), you have to move up *two* lines before the
 > bottom window is enlarged.

OK, here's the function again with that problem fixed.

(defun mouse-drag-modeline (event)
  "Resize a window by dragging its modeline.
This command should be bound to a button-press event in modeline-map.
Holding down a mouse button and moving the mouse up and down will
make the clicked-on window taller or shorter."
  (interactive "e")
  (let ((done nil)
	(echo-keystrokes 0)
	(start-event-frame (event-frame event))
	(start-event-window (event-window event))
	(start-nwindows (count-windows t))
	(last-timestamp 0)
	default-line-height
	modeline-height
	should-enlarge-minibuffer
	event minibuffer y top bot edges wconfig growth)
    (setq minibuffer (minibuffer-window start-event-frame)
	  default-line-height (face-height 'default start-event-window)
	  min-height (* window-min-height default-line-height)
	  modeline-height
	    (if (specifier-instance has-modeline-p start-event-window)
		(+ (face-height 'modeline start-event-window)
		   (* 2 (specifier-instance modeline-shadow-thickness
					    start-event-window)))
	      (* 2 (specifier-instance modeline-shadow-thickness
				       start-event-window))))
    (if (not (eq (window-frame minibuffer) start-event-frame))
	(setq minibuffer nil))
    (if (and (null minibuffer) (one-window-p t))
	(error "Attempt to resize sole window"))
    ;; if this is the bottommost ordinary window, then to
    ;; move its modeline the minibuffer must be enlarged.
    (setq should-enlarge-minibuffer
	  (and minibuffer (window-lowest-p start-event-window)))
    ;; loop reading events
    (while (not done)
      (setq event (next-event event))
      ;; requeue event and quit if this is a misc-user, eval or
      ;;   keypress event.
      ;; quit if this is a button press or release event, or if the event
      ;;   occurred in some other frame.
      ;; drag if this is a mouse motion event and the time
      ;;   between this event and the last event is greater than
      ;;   drag-modeline-event-lag.
      ;; do nothing if this is any other kind of event.
      (cond ((or (misc-user-event-p event)
		 (key-press-event-p event)
		 (eval-event-p event))
	     (setq unread-command-events (nconc unread-command-events
						(list event))
		   done t))
	    ((button-event-p event)
	     (setq done t))
	    ((not (motion-event-p event))
	     nil)
	    ((not (eq start-event-frame (event-frame event)))
	     (setq done t))
	    ((< (abs (- (event-timestamp event) last-timestamp))
		drag-modeline-event-lag)
	     nil)
	    (t
	     (setq last-timestamp (event-timestamp event)
		   y (event-y-pixel event)
		   edges (window-pixel-edges start-event-window)
		   top (nth 1 edges)
		   bot (nth 3 edges))
	     ;; scale back a move that would make the
	     ;; window too short.
	     (cond ((< (- y top (- modeline-height)) min-height)
		    (setq y (+ top min-height (- modeline-height)))))
	     ;; compute size change needed
	     (setq growth (- y bot (/ (- modeline-height) 2))
		   wconfig (current-window-configuration))
	     ;; grow/shrink minibuffer?
	     (if should-enlarge-minibuffer
		 (progn
		   ;; yes.  scale back shrinkage if it
		   ;; would make the minibuffer less than 1
		   ;; line tall.
		   ;;
		   ;; also flip the sign of the computed growth,
		   ;; since if we want to grow the window with the
		   ;; modeline we need to shrink the minibuffer
		   ;; and vice versa.
		   (if (and (> growth 0)
			    (< (- (window-pixel-height minibuffer)
				  growth)
			       default-line-height))
		       (setq growth
			     (- (window-pixel-height minibuffer)
				default-line-height)))
		     (setq growth (- growth))))
	     ;; window grow and shrink by lines not pixels, so
	     ;; divide the pixel height by the height of the
	     ;; default face.
	     (setq growth (/ growth default-line-height))
	     ;; grow/shrink the window
	     (enlarge-window growth nil (if should-enlarge-minibuffer
					    minibuffer
					  start-event-window))
	     ;; if this window's growth caused another
	     ;; window to be deleted because it was too
	     ;; short, rescind the change.
	     ;;
	     ;; if size change caused space to be stolen
	     ;; from a window above this one, rescind the
	     ;; change, but only if we didn't grow/shrink
	     ;; the minibuffer.  minibuffer size changes
	     ;; can cause all windows to shrink... no way
	     ;; around it.
	     (if (or (/= start-nwindows (count-windows t))
		     (and (not should-enlarge-minibuffer)
			  (/= top (nth 1 (window-pixel-edges
					  start-event-window)))))
		 (set-window-configuration wconfig)))))))

