+ even-window-heights nil
+ display-buffer-reuse-frames nil)
+
+(defvar mdw-fallback-window-alist nil
+ "Alist mapping frames to fallback windows.")
+
+(defun mdw-cleanup-fallback-window-alist ()
+ "Remove entries for dead frames and windows from the fallback alist."
+ (let ((prev nil)
+ (cursor mdw-fallback-window-alist))
+ (while cursor
+ (let* ((assoc (car cursor))
+ (tail (cdr cursor)))
+ (cond ((and (frame-live-p (car assoc))
+ (window-live-p (cdr assoc)))
+ (setq prev cursor))
+ ((null prev)
+ (setq mdw-fallback-window-alist tail))
+ (t
+ (setcdr prev tail)))
+ (setq cursor tail)))))
+
+(defun mdw-set-fallback-window (cancel)
+ "Prefer the selected window for pop-up buffers in this frame.
+With a prefix argument, clear the fallback window."
+ (interactive "P")
+ (let* ((frame (selected-frame)) (window (selected-window))
+ (assoc (assq (selected-frame) mdw-fallback-window-alist)))
+ (cond (cancel
+ (cond (assoc
+ (setcdr assoc nil)
+ (message "Fallback window cleared."))
+ (t
+ (message "No fallback window active in this frame."))))
+ ((window-dedicated-p window)
+ (error "Window is dedicated to its buffer."))
+ (t
+ (if assoc (setcdr assoc window)
+ (push (cons frame window) mdw-fallback-window-alist))
+ (message "Fallback window set.")))
+ (mdw-cleanup-fallback-window-alist)))
+
+(defun mdw-last-window-in-frame-p (window)
+ "Return whether WINDOW is the last in its frame."
+ (catch 'done
+ (while window
+ (let ((next (window-next-sibling window)))
+ (while (and next (window-minibuffer-p next))
+ (setq next (window-next-sibling next)))
+ (if next (throw 'done nil)))
+ (setq window (window-parent window)))
+ t))
+
+(defun mdw-display-buffer-in-tolerable-window (buffer alist)
+ "Try finding a tolerable window in which to display BUFFER.
+Begone, foul DWIMmerlaik!
+
+This is all totally subject to arbitrary change in the future, but the
+emphasis is on predictability rather than crazy DWIMmery."
+ (let* ((selected (selected-window)) chosen
+ (fallback (assq (selected-frame) mdw-fallback-window-alist))
+ (full-height-p (window-full-height-p selected))
+ (full-width-p (window-full-width-p selected)))
+ (cond
+
+ ((and fallback (window-live-p (cdr fallback)))
+ ;; There's a fallback window set for this frame. Use it.
+
+ (setq chosen (cdr fallback)
+ selected nil)
+ (display-buffer-record-window 'window chosen buffer))
+
+ ((and full-height-p full-width-p)
+ ;; We're basically the only window in the frame. If we want to get
+ ;; anywhere, we'll have to split the window.
+
+ (let ((width (window-width selected))
+ (preferred-width (mdw-preferred-column-width)))
+ (if (and (>= width (mdw-frame-width-for-columns 2 preferred-width))
+ (mdw-frame-width-quantized-p width preferred-width))
+ (setq chosen (split-window-right preferred-width))
+ (setq chosen (split-window-below)))
+ (display-buffer-record-window 'window chosen buffer)))
+
+ ((mdw-last-window-in-frame-p selected)
+ ;; This is the last window in the frame. I don't think I want to
+ ;; clobber the first window, so rebound and clobber the previous one
+ ;; instead. (This obviously has the same effect if there are only two
+ ;; windows, but seems more useful if there are three.)
+
+ (setq chosen (previous-window selected 'never nil))
+ (display-buffer-record-window 'reuse chosen buffer))
+
+ (t
+ ;; There's another window in front of us. Let's use that one.
+ (setq chosen (next-window selected 'never nil)))
+ (display-buffer-record-window 'reuse chosen buffer))
+
+ (if (eq chosen selected)
+ (error "Failed to select a different window!"))
+
+ (when chosen
+ (with-selected-window chosen (switch-to-buffer buffer)))
+ chosen))
+
+;; Hack the display actions so that they do something sensible.
+(setq display-buffer-fallback-action
+ '((display-buffer--maybe-same-window
+ display-buffer-reuse-window
+ display-buffer-pop-up-window
+ mdw-display-buffer-in-tolerable-window)))