From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juanma Barranquero Newsgroups: gmane.emacs.devel Subject: Re: How to restore the layout? Date: Wed, 26 Jun 2013 19:21:02 +0200 Message-ID: References: <51C5AA68.4000204@alice.it> <51C6B138.50903@gmx.at> <51C6CF57.9030203@alice.it> <51C87C3E.90904@gmx.at> <83ehbrju1d.fsf@gnu.org> <87r4frcq9v.fsf@rosalinde.fritz.box> <87vc5345t3.fsf@gmail.com> <51C8B2C8.4000803@gmx.at> <51C93CDB.2020301@gmx.at> <51C9C790.3020407@gmx.at> <51CA0D4C.7080204@alice.it> <0A6F5672-6149-41B7-B0FF-D4725076B271@mit.edu> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=001a11c1ad3418817104e011e180 X-Trace: ger.gmane.org 1372267309 18907 80.91.229.3 (26 Jun 2013 17:21:49 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 26 Jun 2013 17:21:49 +0000 (UTC) Cc: Drew Adams , Emacs developers To: chad Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Jun 26 19:21:50 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UrtPh-00045b-Do for ged-emacs-devel@m.gmane.org; Wed, 26 Jun 2013 19:21:49 +0200 Original-Received: from localhost ([::1]:60347 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UrtPh-0006hU-1A for ged-emacs-devel@m.gmane.org; Wed, 26 Jun 2013 13:21:49 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49012) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UrtPc-0006hP-VS for emacs-devel@gnu.org; Wed, 26 Jun 2013 13:21:46 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UrtPb-0000Up-F3 for emacs-devel@gnu.org; Wed, 26 Jun 2013 13:21:44 -0400 Original-Received: from mail-ee0-x234.google.com ([2a00:1450:4013:c00::234]:43514) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UrtPb-0000UX-3m for emacs-devel@gnu.org; Wed, 26 Jun 2013 13:21:43 -0400 Original-Received: by mail-ee0-f52.google.com with SMTP id c50so7571781eek.39 for ; Wed, 26 Jun 2013 10:21:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=kAQZI3vcZ1521ttzQuUG+DSbg//F7jyP0UYy1+jQpnU=; b=F4dY9/002fr2F/PHjzfSNWkMCiAg92gKZOwozu+OJ2xbiHc6+hf3EOeppar5zFowgK +QnZzqO15q2zEuUp6SJREJ+IDx8uWOaVLHUx4U37RN22pLaggjd4CXh2XaaWOCKDJJyN QDP3aDcqtkGFZ+kIlaSSMg675eKh94AfuNMCCPNdtRsXq4jlBcelFqtIbftrO5IcfgaX ngtgo54AqHgf0ERrau3JOd2EmDMHu6hQntBJ/kq0BNanej8m9UkpIAlwBL9e52RRLX+l mT9Zx1ZAfGvjpnM6FREbqbbWBfl0r77Em7a08OSCH/2Lebdd1/RFhYkrP0aOqr6nUUw4 Mv/Q== X-Received: by 10.15.76.71 with SMTP id m47mr5034893eey.70.1372267302378; Wed, 26 Jun 2013 10:21:42 -0700 (PDT) Original-Received: by 10.14.142.4 with HTTP; Wed, 26 Jun 2013 10:21:02 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c00::234 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:161104 Archived-At: --001a11c1ad3418817104e011e180 Content-Type: text/plain; charset=UTF-8 This is basically the same patch as before, only slightly more polished. It's surprisingly functional for its tiny size. Changes: - Window/frame config is still saved as a global variable, but not from desktop-globals-to-save, which is a user option. - Some frame parameters are not saved, mostly those that cannot be read back or makes no sense to do so. - Errors while restoring the config do not interrupt the restoring; there's just a message afterwards. There are many things still unimplemented, some of which should be discussed before throwing code at it. From the top of my head: 1) When restoring frames, what to do with the existing ones? They can be reused, or deleted. Reusing them will cause less "flicker". 2) What to do with frames with a buffer-predicate? Currently I'm excluding that frame parameter. It could be saved if it is a symbol, of course. 3) What about maximized / fullscreen frames? Currently they don't restore too well. It would be possible, but the original pre-(fullscreen|maximized) size will not be saved. It could be saved by de-maximizing the frame before saving it and then maximizing it back again, but if the user is just calling desktop-save in the middle of a session, that will make the maximized frame flicker. 4) I'm not saving the `minibuffer' parameter, though I should. It's trivial for t/nil/only, but what about minibuffer . <#window...>? Should we try to save/restore that somehow? 5) Presumably, for Emacs on X I should make sure that each frame is restored in the corresponding display. I'm not yet doing that (I don't have a way to test it). All in all, the patch is small and non-intrusive. Perhaps I could install it (with desktop-save-windows defaulting to nil) so people could experiment and say what works and what doesn't. That would be particularly useful from people who use multi-frame setups (Stefan and Drew come to mind). Comments? J === modified file 'lisp/desktop.el' --- lisp/desktop.el 2013-05-02 17:47:39 +0000 +++ lisp/desktop.el 2013-06-26 17:15:07 +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--window-state nil + "Internal use only.") + ;; ---------------------------------------------------------------------------- ;; Desktop file conflict detection (defvar desktop-file-modtime nil @@ -858,6 +867,37 @@ ;; ---------------------------------------------------------------------------- +(defconst desktop--excluded-frame-parameters + '(minibuffer-predicate + minibuffer + buffer-list + buried-buffer-list + window-id + outer-window-id) + "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 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--window-state + (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--window-state)) + ;;;###autoload (defun desktop-save (dirname &optional release auto-save) "Save the desktop in a desktop file. @@ -896,6 +936,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 +997,20 @@ (defvar desktop-lazy-timer nil) ;; ---------------------------------------------------------------------------- +(defun desktop--restore-windows () + "Restore window/frame configuration. +Internal use only." + (when (and desktop-save-windows desktop--window-state) + (let ((current (frame-list)) + (failure nil)) + (dolist (state desktop--window-state) + (condition-case nil + (window-state-put (cdr state) (frame-root-window (make-frame (car state)))) + (error (setq failure t)))) + (if failure + (message "Error loading window configuration from desktop file") + (mapc #'delete-frame current))))) + ;;;###autoload (defun desktop-read (&optional dirname) "Read and process the desktop file in directory DIRNAME. @@ -1022,6 +1079,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 --001a11c1ad3418817104e011e180 Content-Type: application/octet-stream; name="desktop.patch" Content-Disposition: attachment; filename="desktop.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_hieseiq20 PT09IG1vZGlmaWVkIGZpbGUgJ2xpc3AvZGVza3RvcC5lbCcNCi0tLSBsaXNwL2Rlc2t0b3AuZWwJ MjAxMy0wNS0wMiAxNzo0NzozOSArMDAwMA0KKysrIGxpc3AvZGVza3RvcC5lbAkyMDEzLTA2LTI2 IDE3OjE1OjA3ICswMDAwDQpAQCAtMzcxLDYgKzM3MSwxMiBAQA0KICAgOnR5cGUgJyhyZXBlYXQg c3ltYm9sKQ0KICAgOmdyb3VwICdkZXNrdG9wKQ0KIA0KKyhkZWZjdXN0b20gZGVza3RvcC1zYXZl LXdpbmRvd3MgdA0KKyAgIldoZW4gbm9uLW5pbCwgc2F2ZSB3aW5kb3cvZnJhbWUgY29uZmlndXJh dGlvbiB0byBkZXNrdG9wIGZpbGUuIg0KKyAgOnR5cGUgJ2Jvb2xlYW4NCisgIDpncm91cCAnZGVz a3RvcA0KKyAgOnZlcnNpb24gIjI0LjQiKQ0KKw0KIChkZWZjdXN0b20gZGVza3RvcC1maWxlLW5h bWUtZm9ybWF0ICdhYnNvbHV0ZQ0KICAgIkZvcm1hdCBpbiB3aGljaCBkZXNrdG9wIGZpbGUgbmFt ZXMgc2hvdWxkIGJlIHNhdmVkLg0KIFBvc3NpYmxlIHZhbHVlcyBhcmU6DQpAQCAtNTU2LDYgKzU2 Miw5IEBADQogICAiQ2hlY2tzdW0gb2YgdGhlIGxhc3QgYXV0by1zYXZlZCBjb250ZW50cyBvZiB0 aGUgZGVza3RvcCBmaWxlLg0KIFVzZWQgdG8gYXZvaWQgd3JpdGluZyBjb250ZW50cyB1bmNoYW5n ZWQgYmV0d2VlbiBhdXRvLXNhdmVzLiIpDQogDQorKGRlZnZhciBkZXNrdG9wLS13aW5kb3ctc3Rh dGUgbmlsDQorICAiSW50ZXJuYWwgdXNlIG9ubHkuIikNCisNCiA7OyAtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tDQogOzsgRGVza3RvcCBmaWxlIGNvbmZsaWN0IGRldGVjdGlvbg0KIChkZWZ2YXIgZGVza3Rv cC1maWxlLW1vZHRpbWUgbmlsDQpAQCAtODU4LDYgKzg2NywzNyBAQA0KIA0KIA0KIDs7IC0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0NCisoZGVmY29uc3QgZGVza3RvcC0tZXhjbHVkZWQtZnJhbWUtcGFyYW1l dGVycw0KKyAgJyhtaW5pYnVmZmVyLXByZWRpY2F0ZQ0KKyAgICBtaW5pYnVmZmVyDQorICAgIGJ1 ZmZlci1saXN0DQorICAgIGJ1cmllZC1idWZmZXItbGlzdA0KKyAgICB3aW5kb3ctaWQNCisgICAg b3V0ZXItd2luZG93LWlkKQ0KKyAgIkZyYW1lIHBhcmFtZXRlcnMgbm90IHNhdmVkIG9yIHJlc3Rv cmVkLiIpDQorDQorKGRlZnVuIGRlc2t0b3AtLWZpbHRlci1mcmFtZS1wYXJtcyAoZnJhbWUpDQor ICAiUmV0dXJuIGZyYW1lIHBhcmFtZXRlcnMgb2YgRlJBTUUuDQorUGFyYW1ldGVycyBpbiBgZGVz a3RvcC0tZXhjbHVkZWQtZnJhbWUtcGFyYW1ldGVycycgYXJlIGV4Y2x1ZGVkLg0KK0ludGVybmFs IHVzZSBvbmx5LiINCisgIChsZXQgKHBhcmFtcykNCisgICAgKGRvbGlzdCAocGFyYW0gKGZyYW1l LXBhcmFtZXRlcnMgZnJhbWUpKQ0KKyAgICAgICh1bmxlc3MgKG1lbXEgcGFyYW0gZGVza3RvcC0t ZXhjbHVkZWQtZnJhbWUtcGFyYW1ldGVycykNCisJKHB1c2ggcGFyYW0gcGFyYW1zKSkpDQorICAg IHBhcmFtcykpDQorDQorKGRlZnVuIGRlc2t0b3AtLXNhdmUtd2luZG93cyAoKQ0KKyAgIlNhdmUg d2luZG93L2ZyYW1lIHN0YXRlLCBhcyBhIGdsb2JhbCB2YXJpYWJsZS4NCitJbnRlbmRlZCB0byBi ZSBjYWxsZWQgZnJvbSBgZGVza3RvcC1zYXZlJy4NCitJbnRlcm5hbCB1c2Ugb25seS4iDQorICAo c2V0cSBkZXNrdG9wLS13aW5kb3ctc3RhdGUNCisJKGFuZCBkZXNrdG9wLXNhdmUtd2luZG93cw0K KwkgICAgIChtYXBjYXIgKGxhbWJkYSAoZnJhbWUpDQorCQkgICAgICAgKGNvbnMgKGRlc2t0b3At LWZpbHRlci1mcmFtZS1wYXJtcyBmcmFtZSkNCisJCQkgICAgICh3aW5kb3ctc3RhdGUtZ2V0IChm cmFtZS1yb290LXdpbmRvdyBmcmFtZSkgdCkpKQ0KKwkJICAgICAoZnJhbWUtbGlzdCkpKSkNCisg IChkZXNrdG9wLW91dHZhciAnZGVza3RvcC0td2luZG93LXN0YXRlKSkNCisNCiA7OzsjIyNhdXRv bG9hZA0KIChkZWZ1biBkZXNrdG9wLXNhdmUgKGRpcm5hbWUgJm9wdGlvbmFsIHJlbGVhc2UgYXV0 by1zYXZlKQ0KICAgIlNhdmUgdGhlIGRlc2t0b3AgaW4gYSBkZXNrdG9wIGZpbGUuDQpAQCAtODk2 LDYgKzkzNiw5IEBADQogCSAgKHNhdmUtZXhjdXJzaW9uIChydW4taG9va3MgJ2Rlc2t0b3Atc2F2 ZS1ob29rKSkNCiAJICAoZ290by1jaGFyIChwb2ludC1tYXgpKQ0KIAkgIChpbnNlcnQgIlxuOzsg R2xvYmFsIHNlY3Rpb246XG4iKQ0KKwkgIDs7IENhbGxlZCBoZXJlIGJlY2F1c2Ugd2Ugc2F2ZSB0 aGUgd2luZG93L2ZyYW1lIHN0YXRlIGFzIGEgZ2xvYmFsDQorCSAgOzsgdmFyaWFibGUgZm9yIGNv bXBhdGliaWxpdHkgd2l0aCBwcmV2aW91cyBFbWFjc2VuLg0KKwkgIChkZXNrdG9wLS1zYXZlLXdp bmRvd3MpDQogCSAgKG1hcGMgKGZ1bmN0aW9uIGRlc2t0b3Atb3V0dmFyKSBkZXNrdG9wLWdsb2Jh bHMtdG8tc2F2ZSkNCiAJICAod2hlbiAobWVtcSAna2lsbC1yaW5nIGRlc2t0b3AtZ2xvYmFscy10 by1zYXZlKQ0KIAkgICAgKGluc2VydA0KQEAgLTk1NCw2ICs5OTcsMjAgQEANCiAoZGVmdmFyIGRl c2t0b3AtbGF6eS10aW1lciBuaWwpDQogDQogOzsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KKyhkZWZ1 biBkZXNrdG9wLS1yZXN0b3JlLXdpbmRvd3MgKCkNCisgICJSZXN0b3JlIHdpbmRvdy9mcmFtZSBj b25maWd1cmF0aW9uLg0KK0ludGVybmFsIHVzZSBvbmx5LiINCisgICh3aGVuIChhbmQgZGVza3Rv cC1zYXZlLXdpbmRvd3MgZGVza3RvcC0td2luZG93LXN0YXRlKQ0KKyAgICAobGV0ICgoY3VycmVu dCAoZnJhbWUtbGlzdCkpDQorCSAgKGZhaWx1cmUgbmlsKSkNCisgICAgICAoZG9saXN0IChzdGF0 ZSBkZXNrdG9wLS13aW5kb3ctc3RhdGUpDQorCShjb25kaXRpb24tY2FzZSBuaWwNCisJICAgICh3 aW5kb3ctc3RhdGUtcHV0IChjZHIgc3RhdGUpIChmcmFtZS1yb290LXdpbmRvdyAobWFrZS1mcmFt ZSAoY2FyIHN0YXRlKSkpKQ0KKwkgIChlcnJvciAoc2V0cSBmYWlsdXJlIHQpKSkpDQorICAgICAg KGlmIGZhaWx1cmUNCisJICAobWVzc2FnZSAiRXJyb3IgbG9hZGluZyB3aW5kb3cgY29uZmlndXJh dGlvbiBmcm9tIGRlc2t0b3AgZmlsZSIpDQorCShtYXBjICMnZGVsZXRlLWZyYW1lIGN1cnJlbnQp KSkpKQ0KKw0KIDs7OyMjI2F1dG9sb2FkDQogKGRlZnVuIGRlc2t0b3AtcmVhZCAoJm9wdGlvbmFs IGRpcm5hbWUpDQogICAiUmVhZCBhbmQgcHJvY2VzcyB0aGUgZGVza3RvcCBmaWxlIGluIGRpcmVj dG9yeSBESVJOQU1FLg0KQEAgLTEwMjIsNiArMTA3OSw3IEBADQogCSAgICAoc3dpdGNoLXRvLWJ1 ZmZlciAoY2FyIChidWZmZXItbGlzdCkpKQ0KIAkgICAgKHJ1bi1ob29rcyAnZGVza3RvcC1kZWxh eS1ob29rKQ0KIAkgICAgKHNldHEgZGVza3RvcC1kZWxheS1ob29rIG5pbCkNCisJICAgIChkZXNr dG9wLS1yZXN0b3JlLXdpbmRvd3MpDQogCSAgICAocnVuLWhvb2tzICdkZXNrdG9wLWFmdGVyLXJl YWQtaG9vaykNCiAJICAgIChtZXNzYWdlICJEZXNrdG9wOiAlZCBidWZmZXIlcyByZXN0b3JlZCVz JXMuIg0KIAkJICAgICBkZXNrdG9wLWJ1ZmZlci1vay1jb3VudA0KDQo= --001a11c1ad3418817104e011e180--