]> code.delx.au - gnu-emacs/blobdiff - lisp/frameset.el
; Revert "Use eldoc-documentation-functions"
[gnu-emacs] / lisp / frameset.el
index 5cd921d5f1759e5167f7b4808cfddbbf9b5a9812..2453f57e228a46756f68f5731b9c7125a63c45e0 100644 (file)
@@ -1,6 +1,6 @@
 ;;; frameset.el --- save and restore frame and window setup -*- lexical-binding: t -*-
 
-;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2013-2016 Free Software Foundation, Inc.
 
 ;; Author: Juanma Barranquero <lekktu@gmail.com>
 ;; Keywords: convenience
@@ -354,12 +354,12 @@ Properties can be set with
 ;; Now, what about the filter alist variables? There are three of them,
 ;; though only two sets of parameters:
 ;;
-;; - `frameset-session-filter-alist' contains these filters that allow to
-;;   save and restore framesets in-session, without the need to serialize
-;;   the frameset or save it to disk (for example, to save a frameset in a
-;;   register and restore it later).  Filters in this list do not remove
-;;   live objects, except in `minibuffer', which is dealt especially by
-;;   `frameset-save' / `frameset-restore'.
+;; - `frameset-session-filter-alist' contains these filters that allow
+;;   saving and restoring framesets in-session, without the need to
+;;   serialize the frameset or save it to disk (for example, to save a
+;;   frameset in a register and restore it later).  Filters in this
+;;   list do not remove live objects, except in `minibuffer', which is
+;;   dealt especially by `frameset-save' / `frameset-restore'.
 ;;
 ;; - `frameset-persistent-filter-alist' is the whole deal.  It does all
 ;;   the filtering described above, and the result is ready to be saved on
@@ -417,11 +417,11 @@ Properties can be set with
 ;; `frameset-filter-params' can be useful, even if you're not using
 ;; framesets.  The interface of `frameset-filter-params' is generic
 ;; and does not depend of global state, with one exception: it uses
-;; the internal variable `frameset--target-display' to decide if, and
-;; how, to modify the `display' parameter of FILTERED.  But that
-;; should not represent any problem, because it's only meaningful
-;; when restoring, and customized uses of `frameset-filter-params'
-;; are likely to use their own filter alist and just call
+;; the dynamically bound variable `frameset--target-display' to decide
+;; if, and how, to modify the `display' parameter of FILTERED.  That
+;; should not represent a problem, because it's only meaningful when
+;; restoring, and customized uses of `frameset-filter-params' are
+;; likely to use their own filter alist and just call
 ;;
 ;;   (setq my-filtered (frameset-filter-params my-params my-filters t))
 ;;
@@ -522,13 +522,13 @@ It must return:
 Frame parameters not on this alist are passed intact, as if they were
 defined with ACTION = nil.")
 
-(defvar frameset--target-display nil
-  ;; Either (minibuffer . VALUE) or nil.
-  ;; This refers to the current frame config being processed inside
-  ;; `frameset-restore' and its auxiliary functions (like filtering).
-  ;; If nil, there is no need to change the display.
-  ;; If non-nil, display parameter to use when creating the frame.
-  "Internal use only.")
+;; Dynamically bound in `frameset-save', `frameset-restore'.
+(defvar frameset--target-display)
+;; Either (display . VALUE) or nil.
+;; This refers to the current frame config being processed with
+;; `frameset-filter-params' and its auxiliary filtering functions.
+;; If nil, there is no need to change the display.
+;; If non-nil, display parameter to use when creating the frame.
 
 (defun frameset-switch-to-gui-p (parameters)
   "True when switching to a graphic display.
@@ -664,10 +664,7 @@ nil while the filtering is done to restore it."
     ;; Set the display parameter after filtering, so that filter functions
     ;; have access to its original value.
     (when frameset--target-display
-      (let ((display (assq 'display filtered)))
-       (if display
-           (setcdr display (cdr frameset--target-display))
-         (push frameset--target-display filtered))))
+      (setf (alist-get 'display filtered) (cdr frameset--target-display)))
     filtered))
 
 \f
@@ -760,6 +757,7 @@ PREDICATE is a predicate function, which must return non-nil for frames that
 should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved.
 PROPERTIES is a user-defined property list to add to the frameset."
   (let* ((list (or (copy-sequence frame-list) (frame-list)))
+        (frameset--target-display nil)
         (frames (cl-delete-if-not #'frame-live-p
                                   (if predicate
                                       (cl-delete-if-not predicate list)
@@ -939,7 +937,7 @@ is the parameter alist of the frame being restored.  Internal use only."
 Setting position and size parameters as soon as possible helps reducing
 flickering; other parameters, like `minibuffer' and `border-width', can
 not be changed once the frame has been created.  Internal use only."
-  (cl-loop for param in '(left top with height border-width minibuffer)
+  (cl-loop for param in '(left top width height border-width minibuffer)
           when (assq param parameters) collect it))
 
 (defun frameset--restore-frame (parameters window-state filters force-onscreen)
@@ -949,15 +947,10 @@ PARAMETERS is the frame's parameter alist; WINDOW-STATE is its window state.
 For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'.
 Internal use only."
   (let* ((fullscreen (cdr (assq 'fullscreen parameters)))
-        (lines (assq 'tool-bar-lines parameters))
         (filtered-cfg (frameset-filter-params parameters filters nil))
         (display (cdr (assq 'display filtered-cfg))) ;; post-filtering
         alt-cfg frame)
 
-    ;; This works around bug#14795 (or feature#14795, if not a bug :-)
-    (setq filtered-cfg (assq-delete-all 'tool-bar-lines filtered-cfg))
-    (push '(tool-bar-lines . 0) filtered-cfg)
-
     (when fullscreen
       ;; Currently Emacs has the limitation that it does not record the size
       ;; and position of a frame before maximizing it, so we cannot save &
@@ -1008,8 +1001,7 @@ Internal use only."
               (not (eq (frame-parameter frame 'visibility) 'icon)))
       (frameset-move-onscreen frame force-onscreen))
 
-    ;; Let's give the finishing touches (visibility, tool-bar, maximization).
-    (when lines (push lines alt-cfg))
+    ;; Let's give the finishing touches (visibility, maximization).
     (when alt-cfg (modify-frame-parameters frame alt-cfg))
     ;; Now restore window state.
     (window-state-put window-state (frame-root-window frame) 'safe)
@@ -1030,8 +1022,8 @@ Internal use only."
 (defun frameset-keep-original-display-p (force-display)
   "True if saved frames' displays should be honored.
 For the meaning of FORCE-DISPLAY, see `frameset-restore'."
-  (cond ((daemonp) t)
-       ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display?
+  (cond ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display?
+       ((daemonp) t)
        (t (not force-display))))
 
 (defun frameset-minibufferless-first-p (frame1 _frame2)
@@ -1080,7 +1072,7 @@ FORCE-ONSCREEN can be:
           - a list (LEFT TOP WIDTH HEIGHT), describing the workarea.
           It must return non-nil to force the frame onscreen, nil otherwise.
 
-CLEANUP-FRAMES allows to \"clean up\" the frame list after restoring a frameset:
+CLEANUP-FRAMES allows \"cleaning up\" the frame list after restoring a frameset:
   t        Delete all frames that were not created or restored upon.
   nil      Keep all frames.
   FUNC     A function called with two arguments:
@@ -1141,16 +1133,15 @@ All keyword parameters default to nil."
                     (force-display (if (functionp force-display)
                                        (funcall force-display frame-cfg window-cfg)
                                      force-display))
+                    (frameset--target-display nil)
                     frame to-tty duplicate)
                ;; Only set target if forcing displays and the target display is different.
-               (cond ((frameset-keep-original-display-p force-display)
-                      (setq frameset--target-display nil))
-                     ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg)))
-                      (setq frameset--target-display nil))
-                     (t
-                      (setq frameset--target-display (cons 'display
-                                                           (frame-parameter nil 'display))
-                            to-tty (null (cdr frameset--target-display)))))
+               (unless (or (frameset-keep-original-display-p force-display)
+                           (equal (frame-parameter nil 'display)
+                                  (cdr (assq 'display frame-cfg))))
+                 (setq frameset--target-display (cons 'display
+                                                      (frame-parameter nil 'display))
+                       to-tty (null (cdr frameset--target-display))))
                ;; Time to restore frames and set up their minibuffers as they were.
                ;; We only skip a frame (thus deleting it) if either:
                ;; - we're switching displays, and the user chose the option to delete, or
@@ -1210,9 +1201,6 @@ All keyword parameters default to nil."
     ;; other frames are already visible (discussed in thread for bug#14841).
     (sit-for 0 t)
 
-    ;; Clean temporary caches
-    (setq frameset--target-display nil)
-
     ;; Clean up the frame list
     (when cleanup-frames
       (let ((map nil)
@@ -1233,12 +1221,18 @@ All keyword parameters default to nil."
             (delay-warning 'frameset (error-message-string err) :warning))))))
 
     ;; Make sure there's at least one visible frame.
-    (unless (or (daemonp) (visible-frame-list))
+    (unless (or (daemonp)
+               (catch 'visible
+                 (maphash (lambda (frame _)
+                            (and (frame-live-p frame) (frame-visible-p frame)
+                                 (throw 'visible t)))
+                          frameset--action-map)))
       (make-frame-visible (selected-frame)))))
 
 \f
 ;; Register support
 
+;;;###autoload
 (defun frameset--jump-to-register (data)
   "Restore frameset from DATA stored in register.
 Called from `jump-to-register'.  Internal use only."
@@ -1268,6 +1262,17 @@ Called from `jump-to-register'.  Internal use only."
        (set-frame-selected-window frame window)
        (with-current-buffer buffer (goto-char (aref data 2)))))))
 
+;;;###autoload
+(defun frameset--print-register (data)
+  "Print basic info about frameset stored in DATA.
+Called from `list-registers' and `view-register'.  Internal use only."
+  (let* ((fs (aref data 0))
+        (ns (length (frameset-states fs))))
+    (princ (format "a frameset (%d frame%s, saved on %s)."
+                  ns
+                  (if (= 1 ns) "" "s")
+                  (format-time-string "%c" (frameset-timestamp fs))))))
+
 ;;;###autoload
 (defun frameset-to-register (register)
   "Store the current frameset in register REGISTER.
@@ -1285,7 +1290,7 @@ Interactively, reads the register using `register-read-with-preview'."
                         ;; in the current buffer, so record that separately.
                         (frameset-frame-id nil)
                         (point-marker))
-                :print-func (lambda (_data) (princ "a frameset."))
+                :print-func #'frameset--print-register
                 :jump-func #'frameset--jump-to-register)))
 
 (provide 'frameset)