Subject: Re: bug#10348: 24.0.92; Save and load window states

From: martin rudalics <[email-masked]>
Date: Thu, 22 Dec 2011 18:04:24 +0100

> Steps to reproduce:
 > 1) Start via `emacs -Q'.
 > 2) evaluate the two functions:
 > (defun my-save-frame ()
 >   (interactive)
 >   (let ((buf (find-file-noselect "/tmp/emacs-layout")))
 >     (set-buffer buf)
 >     (erase-buffer)
 >     (print (window-state-get) buf)
 >     (save-buffer)
 >     (kill-buffer)))
 >
 > (defun my-load-frame ()
 >   (interactive)
 >   (let ((buf (find-file-noselect "/tmp/emacs-layout")))
 >     (set-buffer buf)
 >     (beginning-of-buffer)
 >     (window-state-put (read buf))
 >     (kill-buffer)))
 >
 > 3) Do a `M-x my-save-frame' and after that `M-x my-load-frame'
 >
 > Debugger entered--Lisp error: (invalid-read-syntax "#")
 >   read(#<buffer emacs-layout>)
 >   (window-state-put (read buf))
 >   (let ((buf (find-file-noselect "/tmp/emacs-layout"))) (set-buffer buf) (beginning-of-buffer) (window-state-put (read buf)) (save-buffer) (kill-buffer))
 >   my-load-frame()
 >   call-interactively(my-load-frame t nil)
 >   execute-extended-command(nil)
 >   call-interactively(execute-extended-command nil nil)

FWIW, the behavior observed by Michael is caused by the presence of
window objects in the `clone-of' parameters saved by `window-state-get'.
I initially used the window number for this purpose but Stefan later
told me that a user can store arbitrary objects without read syntax in
window parameters so this would have just worked around the current
problem but would not work in general. (The corresponding thread was at
http://lists.gnu.org/archive/html/emacs-diffs/2011-06/msg00321.html but
I have no idea how to retrieve it.)

We have a variety of ways to deal with this:

(1) Do not save the `clone-of' parameter.  It's not yet useful anyway.
     This will not solve the more general problem mentioned above.

(2) Do not save window parameters.  While this should fix all problems
     in the context of this bug report, it will prevent us from saving
     and restoring information needed to make applications work that rely
     on window parameters.

(3) Save only parameters whose value have a read syntax.  This can be
     done either in `window-state-get' or in `my-save-frame'.

(4) Convert parameter values to something with a read syntax.  Basically
     this is what we already do with buffers (using the name of the
     buffer instead of the buffer object) and can be easily done with
     windows (save the window number instead of the window object).

(5) Make functions like `my-load-frame' aware that components of saved
     window states might not have a read syntax and have them take the
     appropriate action.

Unless you have a better suggestion I'll apply (1) for Emacs 24.1 and
try to propose a combination of (3) and (4) for later releases.

martin