all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* desktop.el: Add frames and windows configuration save&restore
@ 2012-01-18 18:09 Jérémy Compostella
  2012-01-18 19:34 ` Drew Adams
  2012-01-18 21:20 ` Stefan Monnier
  0 siblings, 2 replies; 7+ messages in thread
From: Jérémy Compostella @ 2012-01-18 18:09 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]

All,

The attached patch provides the desktop frame and windows configuration
save&restore feature : the desktop module saves all the frame and their
respective windows configuration. On the next Emacs session, after
having restored all the buffers, the desktop module will then restore
all the frame with their window configuration.

This patch probably fits the following TODO item:

 ** Make desktop.el save the "frame configuration" of Emacs (in some
    useful sense).

I have tried to make this feature as customizable as possible:
- This feature is disabled by default with the customizable
  `desktop-save-frames' in order to keep the current behavior for users
  whose could not want this.
- The `desktop-save-selected-frame-only' force the frame and window
  configuration of the current frame only.
- The saved frame parameters is customizable through
  `desktop-frame-parameters-to-save'.
- The saved window properties is customizable through
  `desktop-window-properties-to-save'.

First, I was trying to implement this feature in one of my own Emacs
module but talking with other Emacs users around me I figured out that,
first, this feature is probably expected, and second, it should be
provided by the desktop package.

I've tried to write the best code I could but it's my first "important"
patch to this project and I will be happy to take all your remark into
account ;)

Best regards,

Jérémy


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-desktop.el-Add-frames-and-windows-configuration-save.patch --]
[-- Type: text/x-diff, Size: 8567 bytes --]

From cd4bb24cc4d367af8c0972b1dddbefec04ab18d8 Mon Sep 17 00:00:00 2001
From: Jeremy Compostella <jeremy.compostella@gmail.com>
Date: Mon, 16 Jan 2012 18:07:37 +0100
Subject: [PATCH] desktop.el: Add frames and windows configuration save&restore

When desktop-save-frames is not nil (set to nil by default), the
desktop-save functionn saves all the frame and their window
configuration. All the frames will be automatically restored on the
next Emacs session. When desktop-save-selected-frame-only is not nil
only the current frame is saved and restored.

Signed-off-by: Jeremy Compostella <jeremy.compostella@gmail.com>
---
 lisp/desktop.el |  151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 149 insertions(+), 2 deletions(-)

diff --git a/lisp/desktop.el b/lisp/desktop.el
index 2f79cc0..f7be80f 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -32,6 +32,7 @@
 ;;		- the mark & mark-active
 ;;		- buffer-read-only
 ;;		- some local variables
+;;      - the frames and their associated window configuration
 
 ;; To use this, use customize to turn on desktop-save-mode or add the
 ;; following line somewhere in your .emacs file:
@@ -132,7 +133,7 @@
 
 ;;; Code:
 
-(defvar desktop-file-version "206"
+(defvar desktop-file-version "207"
   "Version number of desktop file format.
 Written into the desktop file and used at desktop read to provide
 backward compatibility.")
@@ -390,6 +391,52 @@ See `desktop-restore-eager'."
   :group 'desktop
   :version "22.1")
 
+(defcustom desktop-save-frames nil
+  "If non-nil, offer to save and restore frames."
+  :type 'boolean
+  :group 'desktop
+  :version "24.1")
+
+(defcustom desktop-save-selected-frame-only nil
+  "If non-nil and `desktop-save-frames' non-nil, only the
+current frame will be saved."
+  :type 'boolean
+  :group 'desktop
+  :version "24.1")
+
+(defcustom desktop-frame-parameters-to-save
+  '(name
+    top
+    left
+    width
+    height
+    modeline
+    fullscreen
+    minibuffer
+    horizontal-scroll-bars
+    font-parameter
+    font
+    font-backend)
+  "List of parameter to save for each frame."
+  :type '(repeat symbol)
+  :group 'desktop)
+
+(defcustom desktop-window-properties-to-save
+  '((set-window-start       . window-start)
+    (set-window-point       . window-point)
+    (set-window-dedicated-p . window-dedicated-p)
+    (set-window-margins     . (lambda (w) `(,(car (window-margins w))
+					    ,(cdr (window-margins w)))))
+    (set-window-hscroll     . window-hscroll)
+    (set-window-scroll-bars . (lambda (w) (let ((scroll (window-scroll-bars w)))
+					    (cons (car scroll) (cddr scroll)))))
+    (set-window-fringes     . window-fringes))
+  "Associative list of window properties to save. Each property
+is a cons cell of two functions \"restore\" and \"save\". The
+\"restore\" function takes a window object and the returned value
+of the \"save\" function. The \"save\" function takes a window object
+as argument.")
+
 ;;;###autoload
 (defvar desktop-save-buffer nil
   "When non-nil, save buffer status in desktop file.
@@ -854,6 +901,92 @@ DIRNAME must be the directory in which the desktop file will be saved."
     ((eq desktop-file-name-format 'local) (file-relative-name filename dirname))
     (t (expand-file-name filename))))
 
+;; ----------------------------------------------------------------------------
+;; Frame and window configuration
+(defun desktop-window-info (window current-window)
+  "Return a list containing the WINDOW buffer-name, the WINDOW egdes, a
+boolean to true when WINDOW is the CURRENT-WINDOW and the WINDOW
+properties list as described by `desktop-window-properties-to-save'."
+  (let ((get-prop (lambda (fun)
+		    (let ((prop (funcall fun window)))
+		      (if (consp prop) prop (list prop))))))
+    (with-current-buffer (window-buffer window)
+      (list (buffer-name)
+	    (window-edges window)
+	    (eq window current-window)
+	    (mapcar (lambda (x) (cons (car x) (funcall get-prop (cdr x))))
+		    desktop-window-properties-to-save)))))
+
+;; ----------------------------------------------------------------------------
+(defun desktop-window-tree (frame)
+  "Return the window tree of frame FRAME replacing the window
+objects by their save informations as returned by `desktop-window-info'"
+  (let* ((current-window (with-selected-frame frame (selected-window)))
+	 (inner '(lambda (wtree)
+		   (if (windowp wtree)
+		       (desktop-window-info wtree current-window)
+		     (setcdr (cdr wtree) (list (mapcar inner (cddr wtree))))
+		     wtree))))
+    (funcall inner (car (window-tree frame)))))
+
+;; ----------------------------------------------------------------------------
+(defun desktop-frame-parameters (frame)
+  "Return the FRAME parameters associative list according to
+`desktop-frame-parameters-to-save'."
+  (mapcar (lambda (param)
+	    (cons param (let ((value (frame-parameter frame param)))
+			  (if (windowp value) t value))))
+	  desktop-frame-parameters-to-save))
+
+;; ----------------------------------------------------------------------------
+(defun desktop-restore-window (window-info)
+  "Restore the selected window properties from
+WINDOW-INFO. WINDOW-INFO is a list as returned by
+`desktop-window-info'."
+  (let* ((buf (get-buffer (car window-info)))
+	 (window (selected-window))
+	 (current-window (when (nth 2 window-info) window)))
+    (when buf
+      (switch-to-buffer buf)
+      (dolist (elm (nth 3 window-info))
+	(apply (car elm) (cons window (cdr elm)))))
+    (other-window 1)
+    current-window))
+
+;; ----------------------------------------------------------------------------
+(defun desktop-restore-window-tree (window-tree)
+  "Restore the selected frame window tree from
+WINDOW-TREE. WINDOW-TREE is a window tree as returned by
+`desktop-window-tree'."
+  (let ((current-window nil))
+    (if (stringp (car window-tree))
+	(desktop-restore-window window-tree)
+      (let* ((direction (car window-tree))
+	     (subtree-list (car (cddr window-tree)))
+	     (last-window (car (last subtree-list))))
+	(dolist (subtree subtree-list)
+	  (unless (eq last-window subtree)
+	    (let* ((edges (nth 1 subtree))
+		   (size (if direction
+			     (- (nth 3 edges) (nth 1 edges))
+			   (- (nth 2 edges) (nth 0 edges)))))
+	      (split-window nil size (not direction))))
+	  (let ((window (desktop-restore-window-tree subtree)))
+	    (when window (setq current-window window))))
+	current-window))))
+
+;; ----------------------------------------------------------------------------
+(defun desktop-restore-frame (use-current-frame frame-params window-tree)
+  "Restore a frame. If USE-CURRENT-FRAME is true, it uses the
+selected frame otherwise it creates a new one. FRAME-PARAMS is a
+frame parameters associative list as returned by
+`desktop-frame-parameters' and WINDOW-TREE is a window tree as
+returned by `desktop-window-tree'."
+  (when use-current-frame
+    (modify-frame-parameters (selected-frame) frame-params))
+  (with-selected-frame (or (and use-current-frame (selected-frame))
+  			   (make-frame frame-params))
+    (select-window (desktop-restore-window-tree window-tree))))
 
 ;; ----------------------------------------------------------------------------
 ;;;###autoload
@@ -920,6 +1053,17 @@ See also `desktop-base-file-name'."
 		  (insert "\n  " (desktop-value-to-string e)))
 		(insert ")\n\n"))))
 
+	  (when (and desktop-save-frames (window-system))
+	    (insert "\n;; Frame and window configuration section:\n")
+	    (let ((frames-to-save (if desktop-save-selected-frame-only
+				      `(,(selected-frame))
+				    (frame-list))))
+	      (dolist (frame frames-to-save)
+		(insert (format "\n(desktop-restore-frame %s '%S '%S)\n"
+				(eq (selected-frame) frame)
+				(desktop-frame-parameters frame)
+				(desktop-window-tree frame))))))
+
 	  (setq default-directory desktop-dirname)
 	  (let ((coding-system-for-write 'emacs-mule))
 	    (write-region (point-min) (point-max) (desktop-full-file-name) nil 'nomessage))
@@ -1008,7 +1152,10 @@ Using it may cause conflicts.  Use it anyway? " owner)))))
 	    ;; move them here.
 	    (mapc 'bury-buffer
 		  (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list))))))
-	    (switch-to-buffer (car (buffer-list)))
+	    ;; If frames are saved/restored the current buffer is
+	    ;; already restored
+	    (unless desktop-save-frames
+	      (switch-to-buffer (car (buffer-list))))
 	    (run-hooks 'desktop-delay-hook)
 	    (setq desktop-delay-hook nil)
 	    (run-hooks 'desktop-after-read-hook)
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: desktop.el: Add frames and windows configuration save&restore
  2012-01-18 18:09 desktop.el: Add frames and windows configuration save&restore Jérémy Compostella
@ 2012-01-18 19:34 ` Drew Adams
  2012-01-18 21:20 ` Stefan Monnier
  1 sibling, 0 replies; 7+ messages in thread
From: Drew Adams @ 2012-01-18 19:34 UTC (permalink / raw)
  To: 'Jérémy Compostella', emacs-devel

Haven't tried it, but it sounds good.  Lots of people have been looking for
something like this.

BTW, why is the `defgroup' for group `desktop' in group `frames'?  Until &
unless Jeremy's enhancement is added, `desktop.el' has _nothing_ (AFAICT) to do
with frames.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: desktop.el: Add frames and windows configuration save&restore
  2012-01-18 18:09 desktop.el: Add frames and windows configuration save&restore Jérémy Compostella
  2012-01-18 19:34 ` Drew Adams
@ 2012-01-18 21:20 ` Stefan Monnier
  2012-01-18 22:30   ` Lennart Borgman
  1 sibling, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2012-01-18 21:20 UTC (permalink / raw)
  To: Jérémy Compostella; +Cc: emacs-devel

> The attached patch provides the desktop frame and windows configuration
> save&restore feature : the desktop module saves all the frame and their

Thanks.  Since we're in feature freeze, this will have to wait.
In the mean time, you may want to check the new window-state-get and
window-state-put functions which should provide you with a form of
window configuration which you can directly print&read, hence
simplifying your code.


        Stefan



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: desktop.el: Add frames and windows configuration save&restore
  2012-01-18 21:20 ` Stefan Monnier
@ 2012-01-18 22:30   ` Lennart Borgman
  2012-01-19 13:07     ` Jérémy Compostella
  0 siblings, 1 reply; 7+ messages in thread
From: Lennart Borgman @ 2012-01-18 22:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Jérémy Compostella, emacs-devel

On Wed, Jan 18, 2012 at 22:20, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>> The attached patch provides the desktop frame and windows configuration
>> save&restore feature : the desktop module saves all the frame and their
>
> Thanks.  Since we're in feature freeze, this will have to wait.
> In the mean time, you may want to check the new window-state-get and
> window-state-put functions which should provide you with a form of
> window configuration which you can directly print&read, hence
> simplifying your code.

Sounds very nice it is finally going to make its way into Emacs.

Jeremy, you may perhaps want to compare to the same functionality
included in nXhtml to see if you find something there you like to
incorporate. (It has been there for some years now, but I have
actually stopped using it myself since I work in a different way
now... ;-)



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: desktop.el: Add frames and windows configuration save&restore
  2012-01-18 22:30   ` Lennart Borgman
@ 2012-01-19 13:07     ` Jérémy Compostella
  2012-01-19 13:18       ` Lennart Borgman
  0 siblings, 1 reply; 7+ messages in thread
From: Jérémy Compostella @ 2012-01-19 13:07 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1270 bytes --]

2012/1/18 Lennart Borgman <lennart.borgman@gmail.com>

> On Wed, Jan 18, 2012 at 22:20, Stefan Monnier <monnier@iro.umontreal.ca>
> wrote:
> >> The attached patch provides the desktop frame and windows configuration
> >> save&restore feature : the desktop module saves all the frame and their
> >
> > Thanks.  Since we're in feature freeze, this will have to wait.
> > In the mean time, you may want to check the new window-state-get and
> > window-state-put functions which should provide you with a form of
> > window configuration which you can directly print&read, hence
> > simplifying your code.
>
I haven't seen these two function functions. As you propose, I will try
to use them. Thanks.

 Sounds very nice it is finally going to make its way into Emacs.
>
> Jeremy, you may perhaps want to compare to the same functionality
> included in nXhtml to see if you find something there you like to
> incorporate. (It has been there for some years now, but I have
> actually stopped using it myself since I work in a different way
> now... ;-)
>
It sounds interesting but I don't know anything about this nxhtml package,
could you please give me some entry point for the feature we are talking
about like one or two function name ? :)

-- 
One Emacs to rule them all

[-- Attachment #2: Type: text/html, Size: 1948 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: desktop.el: Add frames and windows configuration save&restore
  2012-01-19 13:07     ` Jérémy Compostella
@ 2012-01-19 13:18       ` Lennart Borgman
  2012-01-19 14:10         ` Jérémy Compostella
  0 siblings, 1 reply; 7+ messages in thread
From: Lennart Borgman @ 2012-01-19 13:18 UTC (permalink / raw)
  To: Jérémy Compostella; +Cc: Stefan Monnier, emacs-devel

2012/1/19 Jérémy Compostella <jeremy.compostella@gmail.com>:
> 2012/1/18 Lennart Borgman <lennart.borgman@gmail.com>
>>
>> Jeremy, you may perhaps want to compare to the same functionality
>> included in nXhtml to see if you find something there you like to
>> incorporate. (It has been there for some years now, but I have
>> actually stopped using it myself since I work in a different way
>> now... ;-)
>
> It sounds interesting but I don't know anything about this nxhtml package,
> could you please give me some entry point for the feature we are talking
> about like one or two function name ? :)

You will find the package here: https://launchpad.net/nxhtml
The description of it there is perhaps a bit misleading ... ;-)

The easiest way to find the code is just to download it and load the
package. There is a menu entry

  nXhtml - Options - Save/Restore Frames and Windows



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: desktop.el: Add frames and windows configuration save&restore
  2012-01-19 13:18       ` Lennart Borgman
@ 2012-01-19 14:10         ` Jérémy Compostella
  0 siblings, 0 replies; 7+ messages in thread
From: Jérémy Compostella @ 2012-01-19 14:10 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1071 bytes --]

2012/1/19 Lennart Borgman <lennart.borgman@gmail.com>

> 2012/1/19 Jérémy Compostella <jeremy.compostella@gmail.com>:
> > 2012/1/18 Lennart Borgman <lennart.borgman@gmail.com>
> >>
> >> Jeremy, you may perhaps want to compare to the same functionality
> >> included in nXhtml to see if you find something there you like to
> >> incorporate. (It has been there for some years now, but I have
> >> actually stopped using it myself since I work in a different way
> >> now... ;-)
> >
> > It sounds interesting but I don't know anything about this nxhtml
> package,
> > could you please give me some entry point for the feature we are talking
> > about like one or two function name ? :)
>
> You will find the package here: https://launchpad.net/nxhtml
> The description of it there is perhaps a bit misleading ... ;-)
>
> The easiest way to find the code is just to download it and load the
> package. There is a menu entry
>
>  nXhtml - Options - Save/Restore Frames and Windows
>
Indeed, there are maybe concept I may want to incorporate. Thanks.

[-- Attachment #2: Type: text/html, Size: 1588 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-01-19 14:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-18 18:09 desktop.el: Add frames and windows configuration save&restore Jérémy Compostella
2012-01-18 19:34 ` Drew Adams
2012-01-18 21:20 ` Stefan Monnier
2012-01-18 22:30   ` Lennart Borgman
2012-01-19 13:07     ` Jérémy Compostella
2012-01-19 13:18       ` Lennart Borgman
2012-01-19 14:10         ` Jérémy Compostella

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.