emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to restore the layout?


From: Juanma Barranquero
Subject: Re: How to restore the layout?
Date: Thu, 27 Jun 2013 01:05:53 +0200

On Wed, Jun 26, 2013 at 8:27 PM, martin rudalics <address@hidden> wrote:

> The main application is to _restore_ the layout at the _beginning_ of a
> session.  This means that the one initial frame would get reused.

I've implemented reusing all frames according to their displays (that
is, if desktop wants to restore a frame, it will first look on the
list of yet-unused frames for one on the right display; if found, it
will reuse it and delete it from the list; otherwise it will create a
new frame).

It's a pity that, AFAIK, there's no way to delay creating the initial
frame; initial-frame-alist is set after running .emacs, so you cannot
really avoid the resizing / flickering. Other than setting X resources
/ Win32 registry settings just right for the initial frame (which will
backfire as soon as you exit & save the initial frame at another
position / size), the only way to make it more palatable is starting
emacs with --iconic (or perhaps --daemon on POSIX systems?).

> Let's ignore the next issues for the moment.

Well, some of them are hardly ignorable, at least for users with many
frames, minibuffer-only frames, etc. Also the maximized/fullscreen
issue will bother people who usually works with maximized Emacs
windows (assuming such people does exist).

Another issue is at which point in the restore sequence should
windows/frames be restored. Currently I'm doing it between
desktop-delay-hook (which runs when all buffers are loaded) and
desktop-after-read-hook (which happens after a "successful
`desktop-read'"). That would allow the user to intercept the
restoring, though desktop-delay-hook is for internal use. I can of
course add hooks at some points in the save & restore sequences, but
perhaps that's better left until the need arises.

> Please do that.

Let's hear from Stefan & Glenn. Meanwhile, here's the new patch.

   J


=== modified file 'lisp/desktop.el'
--- lisp/desktop.el 2013-05-02 17:47:39 +0000
+++ lisp/desktop.el 2013-06-26 23:03:43 +0000
@@ -371,6 +371,12 @@
   :type '(repeat symbol)
   :group 'desktop)

+(defcustom desktop-save-windows t
+  "When non-nil, save window/frame configuration to desktop file."
+  :type 'boolean
+  :group 'desktop
+  :version "24.4")
+
 (defcustom desktop-file-name-format 'absolute
   "Format in which desktop file names should be saved.
 Possible values are:
@@ -556,6 +562,9 @@
   "Checksum of the last auto-saved contents of the desktop file.
 Used to avoid writing contents unchanged between auto-saves.")

+(defvar desktop--saved-states nil
+  "Internal use only.")
+
 ;; ----------------------------------------------------------------------------
 ;; Desktop file conflict detection
 (defvar desktop-file-modtime nil
@@ -858,6 +867,42 @@


 ;; ----------------------------------------------------------------------------
+(defconst desktop--excluded-frame-parameters
+  '(buffer-list
+    buffer-predicate
+    buried-buffer-list
+    explicit-name
+    font-backend
+    minibuffer
+    name
+    outer-window-id
+    parent-id
+    window-id
+    window-system)
+  "Frame parameters not saved or restored.")
+
+(defun desktop--filter-frame-parms (frame)
+  "Return frame parameters of FRAME.
+Parameters in `desktop--excluded-frame-parameters' are excluded.
+Internal use only."
+  (let (params)
+    (dolist (param (frame-parameters frame))
+      (unless (memq (car param) desktop--excluded-frame-parameters)
+ (push param params)))
+    params))
+
+(defun desktop--save-windows ()
+  "Save window/frame state, as a global variable.
+Intended to be called from `desktop-save'.
+Internal use only."
+  (setq desktop--saved-states
+ (and desktop-save-windows
+     (mapcar (lambda (frame)
+       (cons (desktop--filter-frame-parms frame)
+     (window-state-get (frame-root-window frame) t)))
+     (frame-list))))
+  (desktop-outvar 'desktop--saved-states))
+
 ;;;###autoload
 (defun desktop-save (dirname &optional release auto-save)
   "Save the desktop in a desktop file.
@@ -896,6 +941,9 @@
   (save-excursion (run-hooks 'desktop-save-hook))
   (goto-char (point-max))
   (insert "\n;; Global section:\n")
+  ;; Called here because we save the window/frame state as a global
+  ;; variable for compatibility with previous Emacsen.
+  (desktop--save-windows)
   (mapc (function desktop-outvar) desktop-globals-to-save)
   (when (memq 'kill-ring desktop-globals-to-save)
     (insert
@@ -954,6 +1002,37 @@
 (defvar desktop-lazy-timer nil)

 ;; ----------------------------------------------------------------------------
+(defun desktop--find-frame-in-display (frames display)
+  (let (result)
+    (while (and frames (not result))
+      (if (equal display (frame-parameter (car frames) 'display))
+  (setq result (car frames))
+ (setq frames (cdr frames))))
+    result))
+
+(defun desktop--restore-windows ()
+  "Restore window/frame configuration.
+Internal use only."
+  (when (and desktop-save-windows desktop--saved-states)
+    (condition-case nil
+ (let ((frames (frame-list)))
+  (dolist (state desktop--saved-states)
+    (let* ((fconfig (car state))
+   (display (cdr (assq 'display fconfig)))
+   (frame (desktop--find-frame-in-display frames display)))
+      (if (not frame)
+  ;; no frames in the display -- make a new one
+  (setq frame (make-frame-on-display display fconfig))
+ ;; found one -- reuse and remove from list
+ (setq frames (delq frame frames))
+ (modify-frame-parameters frame fconfig))
+      ;; restore windows
+      (window-state-put (cdr state) (frame-root-window frame) 'safe)))
+  ;; delete any remaining frames
+  (mapc #'delete-frame frames))
+      (error
+       (message "Error loading window configuration from desktop file")))))
+
 ;;;###autoload
 (defun desktop-read (&optional dirname)
   "Read and process the desktop file in directory DIRNAME.
@@ -1022,6 +1101,7 @@
     (switch-to-buffer (car (buffer-list)))
     (run-hooks 'desktop-delay-hook)
     (setq desktop-delay-hook nil)
+    (desktop--restore-windows)
     (run-hooks 'desktop-after-read-hook)
     (message "Desktop: %d buffer%s restored%s%s."
      desktop-buffer-ok-count

Attachment: desktop.patch
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]