diff --git a/hemlock/diredcoms.lisp b/hemlock/diredcoms.lisp
index 082d7458a8e1470a1be87af77990531f5318ef66..34f4c25afd07e4084bc63be88308a1b56353dc8e 100644
--- a/hemlock/diredcoms.lisp
+++ b/hemlock/diredcoms.lisp
@@ -337,6 +337,22 @@
 		    :device :absolute
 		    :directory (subseq dirs 0 (1- (length dirs)))))))
 
+(defcommand "Dired Up Directory" (p)
+  "Invokes \"Dired\" on the directory up one level from the current Dired
+   buffer."
+  "Invokes \"Dired\" on the directory up one level from the current Dired
+   buffer."
+  (declare (ignore p))
+  (unless (hemlock-bound-p 'dired-information)
+    (editor-error "Not in Dired buffer."))
+  (let ((dirs (pathname-directory
+	       (dired-info-pathname (value dired-information)))))
+    (declare (simple-vector dirs))
+    (dired-command nil
+		   (make-pathname
+		    :device :absolute
+		    :directory (subseq dirs 0 (1- (length dirs)))))))
+
 
 
 ;;;; Dired misc. commands -- update, help, line motion.
diff --git a/hemlock/filecoms.lisp b/hemlock/filecoms.lisp
index 8bd09342957b9a2772115f05722ddd720cd74185..4e57e75be16a72e7a06a50a981f7a0891f4bef4a 100644
--- a/hemlock/filecoms.lisp
+++ b/hemlock/filecoms.lisp
@@ -1010,10 +1010,10 @@
   "Delete the current window, going to the previous window."
   "Delete the window we are in, going to the previous window."
   (declare (ignore p))
+  (when (= (length *window-list*) 2)
+    (editor-error "Cannot delete only window."))
   (let ((window (current-window)))
-    (previous-window-command ())
-    (when (eq (current-window) window)
-      (editor-error "Cannot delete current window."))
+    (previous-window-command nil)  
     (delete-window window)))
 
 (defcommand "Line to Top of Window" (p)
@@ -1027,8 +1027,7 @@
   "Deletes the next window on display."
   "Deletes then next window on display."
   (declare (ignore p))
-  (if (eq (next-window (current-window))
-	  (current-window))
+  (if (<= (length *window-list*) 2)
       (editor-error "Cannot delete only window")
       (delete-window (next-window (current-window)))))
 
diff --git a/hemlock/input.lisp b/hemlock/input.lisp
index 2bba85e6c07758d6c7cf65c41a4db9b2714a7d3d..a76b08f72d234c0807c69490569aa9ec07fb6f84 100644
--- a/hemlock/input.lisp
+++ b/hemlock/input.lisp
@@ -406,8 +406,11 @@
 	(update-modeline-field buffer window :more-prompt)
 	(random-typeout-redisplay window))
       (buffer-start (buffer-point buffer))
-      (unless (make-window start :window (make-xwindow-like-hwindow window))
-	(editor-error "Could not create random typeout window.")))))
+      (let* ((xwindow (make-xwindow-like-hwindow window))
+	     (window (make-window start :window xwindow)))
+	(unless window
+	  (xlib:destroy-window xwindow)
+	  (editor-error "Could not create random typeout window."))))))
 
 (defun end-random-typeout (stream)
   (let ((*more-prompt-action* :flush)
diff --git a/hemlock/lispmode.lisp b/hemlock/lispmode.lisp
index d115cdc7515280af6f74a9ae90f4f7e89dde47f7..864ccc9938e21b546ba42319a79de6d32a17507b 100644
--- a/hemlock/lispmode.lisp
+++ b/hemlock/lispmode.lisp
@@ -1191,6 +1191,32 @@ according to the FORWARDP flag."
 	  (ninsert-region point r)
 	  (move-mark point form-start))))))
 
+(defcommand "Extract Form" (p)
+  "Replace the current containing list with the next form.  The entire affected
+   area is pushed onto the kill ring.  If an argument is supplied, that many
+   upward levels of list nesting is replaced by the next form."
+  "Replace the current containing list with the next form.  The entire affected
+   area is pushed onto the kill ring.  If an argument is supplied, that many
+   upward levels of list nesting is replaced by the next form."
+  (let ((point (current-point)))
+    (pre-command-parse-check point)
+    (with-mark ((form-start point :right-inserting)
+		(form-end point))
+      (unless (form-offset form-end 1) (editor-error))
+      (form-offset (move-mark form-start form-end) -1)
+      (with-mark ((containing-start form-start :left-inserting)
+		  (containing-end form-end :left-inserting))
+	(dotimes (i (or p 1))
+	  (unless (and (forward-up-list containing-end)
+		       (backward-up-list containing-start))
+	    (editor-error)))
+	(let ((r (copy-region (region form-start form-end))))
+	  (ring-push (delete-and-save-region
+		      (region containing-start containing-end))
+		     *kill-ring*)
+	  (ninsert-region point r)
+	  (move-mark point form-start))))))
+
 (defcommand "Extract List" (p)
   "Extract the current list.
   The current list replaces the surrounding list.  The entire affected
diff --git a/hemlock/rompsite.lisp b/hemlock/rompsite.lisp
index 36efe589fa5832555effb20bb59713a4d8818f62..f856ff89544d03275f8b07eece62b236e45c2d06 100644
--- a/hemlock/rompsite.lisp
+++ b/hemlock/rompsite.lisp
@@ -211,12 +211,23 @@
   (apply #'xlib:make-event-mask
 	 (append input/boundary-xevents-selection-keys
 		 '(:exposure :structure-notify))))
+(defconstant group-interesting-xevents
+  '(:structure-notify))
+(defconstant group-interesting-xevents-mask
+  (apply #'xlib:make-event-mask group-interesting-xevents))
 
 #+clx
+(defconstant child-interesting-xevents
+  '(:key-press :button-press :button-release :structure-notify :exposure
+    :enter-window :leave-window))
+(defconstant child-interesting-xevents-mask
+  (apply #'xlib:make-event-mask child-interesting-xevents))
+
+(defconstant random-typeout-xevents
+  '(:key-press :button-press :button-release :enter-window :leave-window
+    :exposure))
 (defconstant random-typeout-xevents-mask
-  (apply #'xlib:make-event-mask
-	 (append input/boundary-xevents-selection-keys
-		 '(:exposure))))
+  (apply #'xlib:make-event-mask random-typeout-xevents))
 
 
 #+clx
@@ -229,6 +240,8 @@
 
 (proclaim '(special *editor-input* *real-editor-input*))
 
+(proclaim '(special *editor-input* *real-editor-input*))
+
 ;;; INIT-RAW-IO  --  Internal
 ;;;
 ;;;    This function should be called whenever the editor is entered in a new
@@ -497,13 +510,16 @@
 ;;; 
 #+clx
 (defun default-hemlock-window-mngt (display on)
-  (let ((win (bitmap-hunk-xwindow (window-hunk *current-window*)))
-	(ewin (bitmap-hunk-xwindow (window-hunk *echo-area-window*))))
-    (cond (on (setf (xlib:window-priority ewin) :above)
+  (let ((xparent (window-group-xparent
+		  (bitmap-hunk-window-group (window-hunk *current-window*))))
+	(echo-xparent (window-group-xparent
+		       (bitmap-hunk-window-group
+			(window-hunk *echo-area-window*)))))
+    (cond (on (setf (xlib:window-priority echo-xparent) :above)
 	      (clear-editor-input *editor-input*)
-	      (setf (xlib:window-priority win) :above))
-	  (t (setf (xlib:window-priority ewin) :below)
-	     (setf (xlib:window-priority win) :below))))
+	      (setf (xlib:window-priority xparent) :above))
+	  (t (setf (xlib:window-priority echo-xparent) :below)
+	     (setf (xlib:window-priority xparent) :below))))
   (xlib:display-force-output display))
 
 (defvar *hemlock-window-mngt* nil;#'default-hemlock-window-mngt
diff --git a/hemlock/screen.lisp b/hemlock/screen.lisp
index 076589e1ae97ff8cd6c349686fbc21ad2d2ca57e..3c5d20e45b8b175919f0201f4ee56e73fca21ec9 100644
--- a/hemlock/screen.lisp
+++ b/hemlock/screen.lisp
@@ -51,26 +51,26 @@
 			  x y
 			  (width (value ed::default-window-width))
 			  (height (value ed::default-window-height)))
-  "Make a window that displays text starting at the mark Start.
+  "Make a window that displays text starting at the mark Start.  The default
+   action is to split the current window to make room for the new window.
 
    Modelinep specifies whether the window should display buffer modelines.
 
    Device is the Hemlock device to make the window on.  If it is nil, then
    the window is made on the same device as CURRENT-WINDOW.
 
-   Window is an X window to be used for the Hemlock window.  If not specified,
-   we make one by calling the function in *create-window-hook*.  This hook maps
-   the window to the screen.
+   Window is an X window to be used with the Hemlock window.  The supplied
+   window becomes the parent window for a new group of windows that behave
+   in a stack orientation as windows do on the terminal.
 
    Font-Family is the font-family used for displaying text in the window.
 
-   If Ask-User is non-nil, the user is prompted for missing X, Y, Width, and
-   Height arguments.  X and Y are supplied as pixels, but Width and Height are
-   supplied in characters.  Otherwise, the current window's height is halved,
-   and the new window fills the created space.  If halving the current window
-   results in too small of a window, then a new one is made the same size as
-   the current, offsetting its vertical placement on the screen some pixels."
-  
+   If Ask-User is non-nil, Hemlock prompts the user for missing X, Y, Width,
+   and Height arguments to make a new group of windows that behave in a stack
+   orientation as windows do on the terminal.  This occurs by invoking
+   hi::*create-window-hook*.  X and Y are supplied as pixels, but Width and
+   Height are supplied in characters."
+
   (let* ((device (or device (device-hunk-device (window-hunk (current-window)))))
 	 (window (funcall (device-make-window device)
 			  device start modelinep window font-family
@@ -80,14 +80,26 @@
     window))
 
 (defun delete-window (window)
-  "Make Window go away, removing it from the screen.  Uses *delete-window-hook*
-   to get rid of bitmap window system windows."
-  (when (eq window *current-window*)
-    (error "Cannot kill the current window."))
+  "Make Window go away, removing it from the screen.  This uses
+   hi::*delete-window-hook* to get rid of parent windows on a bitmap device
+   when you delete the last Hemlock window in a group."
+  (when (<= (length *window-list*) 2)
+    (error "Cannot kill the only window."))
   (invoke-hook ed::delete-window-hook window)
   (setq *window-list* (delq window *window-list*))
   (funcall (device-delete-window (device-hunk-device (window-hunk window)))
-	   window))
+	   window)
+  ;;
+  ;; Since the programmer's interface fails to allow users to determine if
+  ;; they're commands delete the current window, this primitive needs to
+  ;; make sure Hemlock doesn't get screwed.  This inadequacy comes from the
+  ;; bitmap window groups and the vague descriptions of PREVIOUS-WINDOW and
+  ;; NEXT-WINDOW.
+  (when (eq window *current-window*)
+    (let ((window (find-if-not #'(lambda (w) (eq w *echo-area-window*))
+			       *window-list*)))
+      (setf (current-buffer) (window-buffer window)
+	    (current-window) window))))
 
 (defun next-window (window)
   "Return the next window after Window, wrapping around if Window is the
diff --git a/hemlock/struct.lisp b/hemlock/struct.lisp
index 56471736cc9726d8f9c0a4cfe6f147571a37d1d3..186e6da496fdc64f6dedeb91535b3320eb8e55f3 100644
--- a/hemlock/struct.lisp
+++ b/hemlock/struct.lisp
@@ -461,7 +461,22 @@
 
 
 
-;;;; Device screen hunks.
+;;;; Device screen hunks and window-group.
+
+;;; Window groups are used to keep track of the old width and height of a group
+;;; so that when a configure-notify event is sent, we can determine if the size
+;;; of the window actually changed or not.
+;;;
+(defstruct (window-group (:print-function %print-window-group)
+			 (:constructor
+			  make-window-group (xparent width height)))
+  xparent
+  width
+  height)
+
+(defun %print-window-group (object stream depth)
+  (declare (ignore object depth))
+  (format stream "#<Hemlock Window Group>"))
 
 ;;; Device-hunks are used to claim a piece of the screen and for ordering
 ;;; pieces of the screen.  Window motion primitives and splitting/merging
@@ -502,7 +517,7 @@
   char-height	      	      ; Height of text body in characters.
   char-width		      ; Width in characters.
   xwindow		      ; X window for this hunk.
-  gcontext		      ; X gcontext for xwindow.
+  gcontext                    ; X gcontext for xwindow.
   start			      ; Head of dis-line list (no dummy).
   end			      ; Exclusive end, i.e. nil if nil-terminated.
   modeline-dis-line	      ; Dis-line for modeline, or NIL if none.
@@ -512,7 +527,8 @@
   font-family		      ; Font-family used in this window.
   input-handler		      ; Gets hunk, char, x, y when char read.
   changed-handler	      ; Gets hunk when size changed.
-  (thumb-bar-p nil))	      ; True if we draw a thumb bar in the top border.
+  (thumb-bar-p nil)	      ; True if we draw a thumb bar in the top border.
+  window-group)		      ; The window-group to which this hunk belongs.
 
 
 ;;; Terminal hunks.