Subject: Re: bug#8856: 24.0.50; regression: special-display-frame is no longer dedicated

From: martin rudalics <[email-masked]>
Date: Sun, 19 Jun 2011 20:40:27 +0200

> I've pared down the code to load.  Just load the attached and then follow the
 > recipe:
 >
 > M-x f TAB ; to display *Completions* frame.
 > C-]       ; to return to top level.
 >
 > M-x f TAB o
 >
 > Or just hit TAB twice in a row: M-x f TAB TAB.  IOW, try to type more
 > input in minibuffer.
 >
 > This then raises the error
 > "Buffer is read-only #<buffer *Completions*>"

It does.  But it does the same on an old verion of trunk here too.  Are
you sure that the version of throw-one.el you sent me works with your
old Emacs?

BTW, in both versions I get the error when I hit c-] already.

Anyway, let's see what happens.  `display-buffer' should execute this
part

       (while (and specifiers (not (window-live-p window)))
	...
	(setq window
                ... 	
	       ((eq method 'fun-with-args)
		(apply (cadr specifier) buffer (cddr specifier))))))

calling

(defun 1on1-display-*Completions*-frame (buf &optional args)
   "..."
   (let (return-window)
     (setq return-window (select-window
                          (funcall special-display-function buf args)))
     (raise-frame)
     (redirect-frame-focus (selected-frame) 1on1-minibuffer-frame)
     return-window))

returning return-window.  After that `display-buffer' leaves the loop
because return-window is hopefully live and

       (or (and (window-live-p window) window)

returns window (that is your return-window).  So I can't imagine that
`display-buffer' got anything to do with this.

However, I noticed that I have changed `pop-to-buffer'.  Does it help if
you use the version below?  It doesn't help here as I explained above.

martin

(defun pop-to-buffer (&optional buffer-or-name specifiers norecord label)
   "..."
   (interactive "BPop to buffer:\nP")
   (let ((buffer (normalize-buffer-to-display buffer-or-name))
	(old-window (selected-window))
	(old-frame (selected-frame))
	new-window new-frame)
     (set-buffer buffer)
     (setq new-window (display-buffer buffer specifiers label))
     (unless (eq new-window old-window)
       ;; `display-buffer' has chosen another window, select it.
       (select-window new-window norecord)
       (setq new-frame (window-frame new-window))
       (unless (eq new-frame old-frame)
	;; `display-buffer' has chosen another frame, make sure it gets
	;; input focus and is risen.
	(select-frame-set-input-focus new-frame)))
     buffer))