Subject: bug#35131: closed (Re: bug#35131: 27.0.50; desktop-save no longer saves register containing frameset)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 04 Apr 2019 17:49:02 +0000

Your bug report

#35131: 27.0.50; desktop-save no longer saves register containing frameset

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
35131: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=35131
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#35131: 27.0.50; desktop-save no longer saves register containing frameset
From: Stefan Monnier <[email-masked]>
To: Tadeus Prastowo <[email-masked]>
Cc: [email-masked]
Date: Thu, 04 Apr 2019 13:48:16 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Tadeus Prastowo <[email-masked]> writes:
> $ emacs -Q
> C-x C-f x.txt
> Hello world!
> C-x C-s
> C-x 3
> C-x 2
> C-x r f =
> C-x 1
> M-x desktop-save RET RET yes RET
> C-x C-c
> $ emacs -Q
> M-x desktop-read RET
> C-x r j =
> The echo area says: Register doesn’t contain a buffer position or configuration

Thanks for the straightforward testcase.
I installed the patch below which seems to fix it,

        Stefan

diff --git a/lisp/desktop.el b/lisp/desktop.el
index acabde5eb2..97c057e201 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -856,6 +856,19 @@ desktop--v2s
                                        `',(cdr el) (cdr el)))
                                  pass1)))
 	 (cons 'may `[,@(mapcar #'cdr pass1)]))))
+    ((and (recordp value) (symbolp (aref value 0)))
+     (let* ((pass1 (let ((res ()))
+                     (dotimes (i (length value))
+                       (push (desktop--v2s (aref value i)) res))
+                     (nreverse res)))
+	    (special (assq nil pass1)))
+       (if special
+	   (cons nil `(record
+                       ,@(mapcar (lambda (el)
+                                   (if (eq (car el) 'must)
+                                       `',(cdr el) (cdr el)))
+                                 pass1)))
+	 (cons 'may (apply #'record (mapcar #'cdr pass1))))))
     ((consp value)
      (let ((p value)
 	   newlist

Subject: 27.0.50; desktop-save no longer saves register containing frameset
From: Tadeus Prastowo <[email-masked]>
To: [email-masked]
Cc: Stefan Monnier <[email-masked]>, emacs-devel <[email-masked]>
Date: Thu, 4 Apr 2019 00:15:41 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

$ emacs -Q
C-x C-f x.txt
Hello world!
C-x C-s
C-x 3
C-x 2
C-x r f =
C-x 1
M-x desktop-save RET RET yes RET
C-x C-c
$ emacs -Q
M-x desktop-read RET
C-x r j =
The echo area says: Register doesn’t contain a buffer position or configuration

Compare this with Emacs 26.1 that has the correct behavior:
$ emacs-26.1 -Q
C-x C-f x.txt
Another hello world!
C-x C-s
C-x 3
C-x 2
C-x r f =
C-x 1
M-x desktop-save RET RET yes RET
C-x C-c
$ emacs-26.1 -Q
M-x desktop-read RET
C-x r j =
I get the saved frameset back, which contains three windows.

The problem can be traced to the following commit (the committer is CC-ed):
-- 8< -----------------------------
commit cd1d9e79f74f137511d49eb9b0ae7ba750ba6c3c
Author: Stefan Monnier <[email-masked]>
Date:   Mon Dec 25 22:51:23 2017 -0500

    * lisp/register.el: Use cl-generic

    (registerv): Make it a "normal"struct.
    (registerv-make): Declare obsolete.
    (register-val-jump-to, register-val-describe, register-val-insert):
    New generic functions.
    (jump-to-register, describe-register-1, insert-register): Use them.

    * lisp/emacs-lisp/cl-generic.el: Prefill a combination of struct+typeof.
    (cl--generic-prefill-dispatchers): Allow a list of specializers.
-- 8< -----------------------------

The offending diff is shown below:
-- 8< -----------------------------
diff --git a/lisp/register.el b/lisp/register.el
index 23eefd0..0fdcd51 100644
--- a/lisp/register.el
+++ b/lisp/register.el
@@ -39,9 +39,7 @@
   (registerv (:constructor nil)
          (:constructor registerv--make (&optional data print-func
                               jump-func insert-func))
-         (:copier nil)
-         (:type vector)
-         :named)
+         (:copier nil))
   (data        nil :read-only t)
   (print-func  nil :read-only t)
   (jump-func   nil :read-only t)
-- 8< -----------------------------

Specifically, because type vector is dropped, frameset.el in its using
of registerv-make to save a frameset results in register-alist item
that is no longer a vector (C-h v register-alist shows `(61 .
#s(registerv :data [[frameset 1...' in 27.0.50, not `(61 . [registerv
[[frameset 1...' that is shown in Emacs 26.1).  Since it is no longer
a vector, desktop.el upon desktop-save does not serialize the item in
a format that can be recognized by register.el after desktop-read.

Since the offending commit deprecates the use of registerv-make, this
bug can be easily be killed by making frameset.el define function
`register-val-insert' that saves a frameset as a vector, modifying
function `frameset-to-register' accordingly.

@Stefan: could you do that, please?  Thank you.

-- 
Best regards,
Tadeus