Subject: bug#55070: 28.1; desktop-load doesn't work in -nw (non-gui) emacs

From: Eli Zaretskii <[email-masked]>
Date: Sat, 30 Apr 2022 11:42:45 +0300

> From: Juri Linkov <[email-masked]>
> Cc: Eli Zaretskii <[email-masked]>,  <[email-masked]>,  <[email-masked]>
> Date: Thu, 28 Apr 2022 20:39:46 +0300
> 
> > The patch worked great for me.  I can restore saved sessions
> > in both GUI and -nw mode.  Thanks much.
> 
> Thanks for confirming that the patch fixed the bug.
> Then let's wait when Eli will finish writing a better patch
> that does the same.

Please try the patch below.  Its main idea is that calling
frameset-move-onscreen makes no sense on a text-mode display, so I
made desktop.el force frameset.el avoid calling that function in this
case.  The rest is basically a simple cleanup.

In addition to testing the use case of both saving and restoring the
desktop in a -nw session, I'd appreciate testing when the desktop was
saved in a GUI session and is restored in a TTY session, and vice
versa.  Likewise for when the session in which the desktop is restored
is a daemon session -- the main concern there is that a daemon session
shouldn't restore frames at all.

Thanks.

diff --git a/lisp/desktop.el b/lisp/desktop.el
index f41a41c..e438b98 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -434,7 +434,9 @@ desktop-restore-forces-onscreen
 Note that checking of frame boundaries is only approximate.
 It can fail to reliably detect frames whose onscreen/offscreen state
 depends on a few pixels, especially near the right / bottom borders
-of the screen."
+of the screen.
+Text-mode frames are always considered onscreen, so this option has
+no effect on restoring frames in a non-GUI session."
   :type '(choice (const :tag "Only fully offscreen frames" t)
 		 (const :tag "Also partially offscreen frames" all)
 		 (const :tag "Do not force frames onscreen" nil))
@@ -1251,7 +1253,11 @@ desktop-lazy-timer
 ;; ----------------------------------------------------------------------------
 (defun desktop-restoring-frameset-p ()
   "True if calling `desktop-restore-frameset' will actually restore it."
-  (and desktop-restore-frames desktop-saved-frameset (display-graphic-p) t))
+  (and desktop-restore-frames desktop-saved-frameset
+       ;; Don't restore frames when the selected frame is the daemon's
+       ;; initial frame.
+       (not (and (daemonp) (not (frame-parameter nil 'client))))
+       t))
 
 (defun desktop-restore-frameset ()
   "Restore the state of a set of frames.
@@ -1262,7 +1268,8 @@ desktop-restore-frameset
 		      :reuse-frames (eq desktop-restore-reuses-frames t)
 		      :cleanup-frames (not (eq desktop-restore-reuses-frames 'keep))
 		      :force-display desktop-restore-in-current-display
-		      :force-onscreen desktop-restore-forces-onscreen)))
+		      :force-onscreen (and desktop-restore-forces-onscreen
+                                           (display-graphic-p)))))
 
 ;; Just to silence the byte compiler.
 ;; Dynamically bound in `desktop-read'.
diff --git a/lisp/frameset.el b/lisp/frameset.el
index 05884ee..c97cef0 100644
--- a/lisp/frameset.el
+++ b/lisp/frameset.el
@@ -448,6 +448,7 @@ frameset-session-filter-alist
 (defvar frameset-persistent-filter-alist
   (append
    '((background-color            . frameset-filter-sanitize-color)
+     (bottom                      . frameset-filter-shelve-param)
      (buffer-list                 . :never)
      (buffer-predicate            . :never)
      (buried-buffer-list          . :never)
@@ -464,13 +465,20 @@ frameset-persistent-filter-alist
      (frameset--text-pixel-height . :save)
      (frameset--text-pixel-width  . :save)
      (fullscreen                  . frameset-filter-shelve-param)
+     (GUI:bottom                  . frameset-filter-unshelve-param)
      (GUI:font                    . frameset-filter-unshelve-param)
      (GUI:fullscreen              . frameset-filter-unshelve-param)
      (GUI:height                  . frameset-filter-unshelve-param)
+     (GUI:left                    . frameset-filter-unshelve-param)
+     (GUI:right                   . frameset-filter-unshelve-param)
+     (GUI:top                     . frameset-filter-unshelve-param)
      (GUI:width                   . frameset-filter-unshelve-param)
      (height                      . frameset-filter-shelve-param)
+     (left                        . frameset-filter-shelve-param)
      (parent-frame                . :never)
      (mouse-wheel-frame           . :never)
+     (right                       . frameset-filter-shelve-param)
+     (top                         . frameset-filter-shelve-param)
      (tty                         . frameset-filter-tty-to-GUI)
      (tty-type                    . frameset-filter-tty-to-GUI)
      (width                       . frameset-filter-shelve-param)