diff options
| author | Juanma Barranquero | 2013-08-05 06:45:17 +0200 |
|---|---|---|
| committer | Juanma Barranquero | 2013-08-05 06:45:17 +0200 |
| commit | 063233c357f823efc7abd61469725a42da90a1a6 (patch) | |
| tree | f2f422781966236d2123ca89b8e8ddf74df4fb1c | |
| parent | 8f3a2c2659ddee1ae84b4b8bb28f6c388f87fd0f (diff) | |
| download | emacs-063233c357f823efc7abd61469725a42da90a1a6.tar.gz emacs-063233c357f823efc7abd61469725a42da90a1a6.zip | |
* lisp/frameset.el: Miscellaneous cleanups.
(frameset): Add docstring. Move :version property to its
own `version' slot.
(frameset-copy): Rename from copy-frameset.
(frameset-p): Check more thoroughly.
(frameset-prop): Do not check for :version, which is no longer a prop.
(frameset-live-filter-alist, frameset-persistent-filter-alist):
Use new :never value instead of t.
(frameset-filter-alist): Expand and clarify docstring.
(frameset-filter-tty-to-GUI, frameset-filter-sanitize-color)
(frameset-filter-minibuffer, frameset-filter-save-param)
(frameset-filter-restore-param, frameset-filter-iconified):
Add pointer to docstring of frameset-filter-alist.
(frameset-filter-params): Rename filter values to be more meaningful:
:never instead of t, and reverse the meanings of :save and :restore.
(frameset--process-minibuffer-frames): Clarify error message.
(frameset-save): Avoid unnecessary and confusing call to framep.
Use new BOA constructor for framesets.
(frameset--reuse-list): Doc fix.
(frameset--restore-frame): Rename from frameset--get-frame. Doc fix.
(frameset--minibufferless-last-p): Rename from frameset--sort-states.
(frameset-minibufferless-first-p): Doc fix.
Rename from frameset-sort-frames-for-deletion.
(frameset-restore): Doc fixes. Use new function names.
Most changes suggested by Drew Adams <drew.adams@oracle.com>.
* lisp/desktop.el (desktop-clear): Use new name of sort predicate.
| -rw-r--r-- | lisp/ChangeLog | 29 | ||||
| -rw-r--r-- | lisp/desktop.el | 2 | ||||
| -rw-r--r-- | lisp/frameset.el | 294 |
3 files changed, 208 insertions, 117 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index de1da73bbb1..0c4240c9075 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,32 @@ | |||
| 1 | 2013-08-05 Juanma Barranquero <lekktu@gmail.com> | ||
| 2 | |||
| 3 | * desktop.el (desktop-clear): Use new name of sort predicate. | ||
| 4 | |||
| 5 | * frameset.el (frameset): Add docstring. Move :version property to its | ||
| 6 | own `version' slot. | ||
| 7 | (frameset-copy): Rename from copy-frameset. | ||
| 8 | (frameset-p): Check more thoroughly. | ||
| 9 | (frameset-prop): Do not check for :version, which is no longer a prop. | ||
| 10 | (frameset-live-filter-alist, frameset-persistent-filter-alist): | ||
| 11 | Use new :never value instead of t. | ||
| 12 | (frameset-filter-alist): Expand and clarify docstring. | ||
| 13 | (frameset-filter-tty-to-GUI, frameset-filter-sanitize-color) | ||
| 14 | (frameset-filter-minibuffer, frameset-filter-save-param) | ||
| 15 | (frameset-filter-restore-param, frameset-filter-iconified): | ||
| 16 | Add pointer to docstring of frameset-filter-alist. | ||
| 17 | (frameset-filter-params): Rename filter values to be more meaningful: | ||
| 18 | :never instead of t, and reverse the meanings of :save and :restore. | ||
| 19 | (frameset--process-minibuffer-frames): Clarify error message. | ||
| 20 | (frameset-save): Avoid unnecessary and confusing call to framep. | ||
| 21 | Use new BOA constructor for framesets. | ||
| 22 | (frameset--reuse-list): Doc fix. | ||
| 23 | (frameset--restore-frame): Rename from frameset--get-frame. Doc fix. | ||
| 24 | (frameset--minibufferless-last-p): Rename from frameset--sort-states. | ||
| 25 | (frameset-minibufferless-first-p): Doc fix. | ||
| 26 | Rename from frameset-sort-frames-for-deletion. | ||
| 27 | (frameset-restore): Doc fixes. Use new function names. | ||
| 28 | Most changes suggested by Drew Adams <drew.adams@oracle.com>. | ||
| 29 | |||
| 1 | 2013-08-04 Juanma Barranquero <lekktu@gmail.com> | 30 | 2013-08-04 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 31 | ||
| 3 | * desktop.el (desktop-restore-forces-onscreen) | 32 | * desktop.el (desktop-restore-forces-onscreen) |
diff --git a/lisp/desktop.el b/lisp/desktop.el index ab78663c3d0..76aa30e4090 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el | |||
| @@ -671,7 +671,7 @@ if different)." | |||
| 671 | (called-interactively-p 'any)) | 671 | (called-interactively-p 'any)) |
| 672 | (let* ((this (selected-frame)) | 672 | (let* ((this (selected-frame)) |
| 673 | (mini (window-frame (minibuffer-window this)))) ; in case they difer | 673 | (mini (window-frame (minibuffer-window this)))) ; in case they difer |
| 674 | (dolist (frame (sort (frame-list) #'frameset-sort-frames-for-deletion)) | 674 | (dolist (frame (sort (frame-list) #'frameset-minibufferless-first-p)) |
| 675 | (condition-case err | 675 | (condition-case err |
| 676 | (unless (or (eq frame this) | 676 | (unless (or (eq frame this) |
| 677 | (eq frame mini) | 677 | (eq frame mini) |
diff --git a/lisp/frameset.el b/lisp/frameset.el index b24e4ed9362..c22d71b7d79 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el | |||
| @@ -41,48 +41,77 @@ | |||
| 41 | (require 'cl-lib) | 41 | (require 'cl-lib) |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | ;; Framesets have two fields: | ||
| 45 | ;; - properties: a property list to store both frameset-specific and | ||
| 46 | ;; user-defined serializable data. Currently defined properties | ||
| 47 | ;; include: | ||
| 48 | ;; :version ID - Identifies the version of the frameset struct; | ||
| 49 | ;; this is the only property always present and | ||
| 50 | ;; must not be modified. | ||
| 51 | ;; :app APPINFO - Freeform. Can be used by applications and | ||
| 52 | ;; packages to indicate the intended (but by no | ||
| 53 | ;; means exclusive) use of the frameset. For | ||
| 54 | ;; example, currently desktop.el sets :app to | ||
| 55 | ;; `(desktop . ,desktop-file-version). | ||
| 56 | ;; :name NAME - The name of the frameset instance; a string. | ||
| 57 | ;; :desc TEXT - A description for user consumption (to choose | ||
| 58 | ;; among framesets, etc.); a string. | ||
| 59 | ;; - states: an alist of items (FRAME-PARAMETERS . WINDOW-STATE) in | ||
| 60 | ;; no particular order. Each item represents a frame to be | ||
| 61 | ;; restored. | ||
| 62 | |||
| 63 | (cl-defstruct (frameset (:type list) :named | 44 | (cl-defstruct (frameset (:type list) :named |
| 64 | (:copier nil) | 45 | (:copier nil) |
| 65 | (:predicate nil)) | 46 | (:predicate nil) |
| 66 | properties ;; property list | 47 | ;; A BOA constructor, not the default "keywordy" one. |
| 67 | states) ;; list of conses (frame-state . window-state) | 48 | (:constructor make-frameset (properties states))) |
| 68 | 49 | ||
| 69 | (defun copy-frameset (frameset) | 50 | "A frameset encapsulates a serializable view of a set of frames and windows. |
| 51 | |||
| 52 | It contains the following slots, which can be accessed with | ||
| 53 | \(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): | ||
| 54 | |||
| 55 | version A non-modifiable version number, identifying the format | ||
| 56 | of the frameset struct. Currently its value is 1. | ||
| 57 | properties A property list, to store both frameset-specific and | ||
| 58 | user-defined serializable data (some suggested properties | ||
| 59 | are described below). | ||
| 60 | states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no | ||
| 61 | particular order. Each item represents a frame to be | ||
| 62 | restored. FRAME-PARAMETERS is a frame's parameter list, | ||
| 63 | extracted with (frame-parameters FRAME) and filtered through | ||
| 64 | `frame-parameters-alist' or a similar filter alist. | ||
| 65 | WINDOW-STATE is the output of `window-state-get', when | ||
| 66 | applied to the root window of the frame. | ||
| 67 | |||
| 68 | Some suggested properties: | ||
| 69 | |||
| 70 | :app APPINFO Can be used by applications and packages to indicate the | ||
| 71 | intended (but by no means exclusive) use of the frameset. | ||
| 72 | Freeform. For example, currently desktop.el framesets set | ||
| 73 | :app to `(desktop . ,desktop-file-version). | ||
| 74 | :name NAME The name of the frameset instance; a string. | ||
| 75 | :desc TEXT A description for user consumption (to show in a menu to | ||
| 76 | choose among framesets, etc.); a string. | ||
| 77 | |||
| 78 | A frameset is intended to be used through the following simple API: | ||
| 79 | |||
| 80 | - `frameset-save' captures all or a subset of the live frames, and returns | ||
| 81 | a serializable snapshot of them (a frameset). | ||
| 82 | - `frameset-restore' takes a frameset, and restores the frames and windows | ||
| 83 | it describes, as faithfully as possible. | ||
| 84 | - `frameset-p' is the predicate for the frameset type. It returns nil | ||
| 85 | for non-frameset objects, and the frameset version number (see below) | ||
| 86 | for frameset objects. | ||
| 87 | - `frameset-copy' returns a deep copy of a frameset. | ||
| 88 | - `frameset-prop' is a `setf'able accessor for the contents of the | ||
| 89 | `properties' slot. | ||
| 90 | - The `frameset-SLOT' accessors described above." | ||
| 91 | |||
| 92 | (version 1 :read-only t) | ||
| 93 | properties states) | ||
| 94 | |||
| 95 | (defun frameset-copy (frameset) | ||
| 70 | "Return a copy of FRAMESET. | 96 | "Return a copy of FRAMESET. |
| 71 | This is a deep copy done with `copy-tree'." | 97 | This is a deep copy done with `copy-tree'." |
| 72 | (copy-tree frameset t)) | 98 | (copy-tree frameset t)) |
| 73 | 99 | ||
| 74 | ;;;###autoload | 100 | ;;;###autoload |
| 75 | (defun frameset-p (frameset) | 101 | (defun frameset-p (frameset) |
| 76 | "If FRAMESET is a frameset, return its :version. | 102 | "If FRAMESET is a frameset, return its version number. |
| 77 | Else return nil." | 103 | Else return nil." |
| 78 | (and (eq (car-safe frameset) 'frameset) | 104 | (and (eq (car-safe frameset) 'frameset) ; is a list |
| 79 | (plist-get (cl-second frameset) :version))) | 105 | (integerp (nth 1 frameset)) ; version is an int |
| 106 | (nth 2 frameset) ; properties is non-null | ||
| 107 | (nth 3 frameset) ; states is non-null | ||
| 108 | (nth 1 frameset))) ; return version | ||
| 80 | 109 | ||
| 81 | ;; A setf'able accessor to the frameset's properties | 110 | ;; A setf'able accessor to the frameset's properties |
| 82 | (defun frameset-prop (frameset prop) | 111 | (defun frameset-prop (frameset prop) |
| 83 | "Return the value of the PROP property of FRAMESET. | 112 | "Return the value of the PROP property of FRAMESET. |
| 84 | 113 | ||
| 85 | Properties other than :version can be set with | 114 | Properties can be set with |
| 86 | 115 | ||
| 87 | (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" | 116 | (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" |
| 88 | (plist-get (frameset-properties frameset) prop)) | 117 | (plist-get (frameset-properties frameset) prop)) |
| @@ -90,7 +119,6 @@ Properties other than :version can be set with | |||
| 90 | (gv-define-setter frameset-prop (val fs prop) | 119 | (gv-define-setter frameset-prop (val fs prop) |
| 91 | (macroexp-let2 nil v val | 120 | (macroexp-let2 nil v val |
| 92 | `(progn | 121 | `(progn |
| 93 | (cl-assert (not (eq ,prop :version)) t ":version can not be set") | ||
| 94 | (setf (frameset-properties ,fs) | 122 | (setf (frameset-properties ,fs) |
| 95 | (plist-put (frameset-properties ,fs) ,prop ,v)) | 123 | (plist-put (frameset-properties ,fs) ,prop ,v)) |
| 96 | ,v))) | 124 | ,v))) |
| @@ -100,7 +128,7 @@ Properties other than :version can be set with | |||
| 100 | 128 | ||
| 101 | ;;;###autoload | 129 | ;;;###autoload |
| 102 | (defvar frameset-live-filter-alist | 130 | (defvar frameset-live-filter-alist |
| 103 | '((name . t) | 131 | '((name . :never) |
| 104 | (minibuffer . frameset-filter-minibuffer) | 132 | (minibuffer . frameset-filter-minibuffer) |
| 105 | (top . frameset-filter-iconified)) | 133 | (top . frameset-filter-iconified)) |
| 106 | "Minimum set of parameters to filter for live (on-session) framesets. | 134 | "Minimum set of parameters to filter for live (on-session) framesets. |
| @@ -110,25 +138,25 @@ See `frameset-filter-alist' for a full description.") | |||
| 110 | (defvar frameset-persistent-filter-alist | 138 | (defvar frameset-persistent-filter-alist |
| 111 | (nconc | 139 | (nconc |
| 112 | '((background-color . frameset-filter-sanitize-color) | 140 | '((background-color . frameset-filter-sanitize-color) |
| 113 | (buffer-list . t) | 141 | (buffer-list . :never) |
| 114 | (buffer-predicate . t) | 142 | (buffer-predicate . :never) |
| 115 | (buried-buffer-list . t) | 143 | (buried-buffer-list . :never) |
| 116 | (font . frameset-filter-save-parm) | 144 | (font . frameset-filter-save-param) |
| 117 | (foreground-color . frameset-filter-sanitize-color) | 145 | (foreground-color . frameset-filter-sanitize-color) |
| 118 | (fullscreen . frameset-filter-save-parm) | 146 | (fullscreen . frameset-filter-save-param) |
| 119 | (GUI:font . frameset-filter-restore-parm) | 147 | (GUI:font . frameset-filter-restore-param) |
| 120 | (GUI:fullscreen . frameset-filter-restore-parm) | 148 | (GUI:fullscreen . frameset-filter-restore-param) |
| 121 | (GUI:height . frameset-filter-restore-parm) | 149 | (GUI:height . frameset-filter-restore-param) |
| 122 | (GUI:width . frameset-filter-restore-parm) | 150 | (GUI:width . frameset-filter-restore-param) |
| 123 | (height . frameset-filter-save-parm) | 151 | (height . frameset-filter-save-param) |
| 124 | (left . frameset-filter-iconified) | 152 | (left . frameset-filter-iconified) |
| 125 | (outer-window-id . t) | 153 | (outer-window-id . :never) |
| 126 | (parent-id . t) | 154 | (parent-id . :never) |
| 127 | (tty . frameset-filter-tty-to-GUI) | 155 | (tty . frameset-filter-tty-to-GUI) |
| 128 | (tty-type . frameset-filter-tty-to-GUI) | 156 | (tty-type . frameset-filter-tty-to-GUI) |
| 129 | (width . frameset-filter-save-parm) | 157 | (width . frameset-filter-save-param) |
| 130 | (window-id . t) | 158 | (window-id . :never) |
| 131 | (window-system . t)) | 159 | (window-system . :never)) |
| 132 | frameset-live-filter-alist) | 160 | frameset-live-filter-alist) |
| 133 | "Recommended set of parameters to filter for persistent framesets. | 161 | "Recommended set of parameters to filter for persistent framesets. |
| 134 | See `frameset-filter-alist' for a full description.") | 162 | See `frameset-filter-alist' for a full description.") |
| @@ -137,35 +165,48 @@ See `frameset-filter-alist' for a full description.") | |||
| 137 | (defvar frameset-filter-alist frameset-persistent-filter-alist | 165 | (defvar frameset-filter-alist frameset-persistent-filter-alist |
| 138 | "Alist of frame parameters and filtering functions. | 166 | "Alist of frame parameters and filtering functions. |
| 139 | 167 | ||
| 140 | Each element is a cons (PARAM . ACTION), where PARAM is a parameter | 168 | This alist is the default value of the :filters arguments of |
| 141 | name (a symbol identifying a frame parameter), and ACTION can be: | 169 | `frameset-save' and `frameset-restore' (which see). On saving, |
| 142 | 170 | PARAMETERS is the parameter list of each frame processed, and | |
| 143 | t The parameter is always removed from the parameter list. | 171 | FILTERED is the parameter list that gets saved to the frameset. |
| 144 | :save The parameter is removed when saving the frame. | 172 | On restoring, PARAMETERS is the parameter list extracted from the |
| 145 | :restore The parameter is removed when restoring the frame. | 173 | frameset, and FILTERED is the resulting frame parameter list used |
| 174 | to restore the frame. | ||
| 175 | |||
| 176 | Elements of this alist are conses (PARAM . ACTION), where PARAM | ||
| 177 | is a parameter name (a symbol identifying a frame parameter), and | ||
| 178 | ACTION can be: | ||
| 179 | |||
| 180 | nil The parameter is copied to FILTERED. | ||
| 181 | :never The parameter is never copied to FILTERED. | ||
| 182 | :save The parameter is copied only when saving the frame. | ||
| 183 | :restore The parameter is copied only when restoring the frame. | ||
| 146 | FILTER A filter function. | 184 | FILTER A filter function. |
| 147 | 185 | ||
| 148 | FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). | 186 | FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). |
| 149 | It will be called with four arguments CURRENT, FILTERED, PARAMETERS | 187 | FILTER-FUN is called with four arguments CURRENT, FILTERED, PARAMETERS and |
| 150 | and SAVING, plus any additional ARGS: | 188 | SAVING, plus any additional ARGS: |
| 151 | 189 | ||
| 152 | CURRENT A cons (PARAM . VALUE), where PARAM is the one being | 190 | CURRENT A cons (PARAM . VALUE), where PARAM is the one being |
| 153 | filtered and VALUE is its current value. | 191 | filtered and VALUE is its current value. |
| 154 | FILTERED The alist of parameters filtered so far. | 192 | FILTERED The resulting alist (so far). |
| 155 | PARAMETERS The complete alist of parameters being filtered, | 193 | PARAMETERS The complete alist of parameters being filtered, |
| 156 | SAVING Non-nil if filtering before saving state, nil otherwise. | 194 | SAVING Non-nil if filtering before saving state, nil if filtering |
| 195 | before restoring it. | ||
| 157 | 196 | ||
| 158 | The FILTER-FUN function must return: | 197 | FILTER-FUN must return: |
| 159 | nil CURRENT is removed from the list. | 198 | nil Skip CURRENT (do not add it to FILTERED). |
| 160 | t CURRENT is left as is. | 199 | t Add CURRENT to FILTERED as is. |
| 161 | (PARAM' . VALUE') Replace CURRENT with this. | 200 | (NEW-PARAM . NEW-VALUE) Add this to FILTERED instead of CURRENT. |
| 201 | |||
| 202 | Frame parameters not on this alist are passed intact, as if they were | ||
| 203 | defined with ACTION = nil.") | ||
| 162 | 204 | ||
| 163 | Frame parameters not on this list are passed intact.") | ||
| 164 | 205 | ||
| 165 | (defvar frameset--target-display nil | 206 | (defvar frameset--target-display nil |
| 166 | ;; Either (minibuffer . VALUE) or nil. | 207 | ;; Either (minibuffer . VALUE) or nil. |
| 167 | ;; This refers to the current frame config being processed inside | 208 | ;; This refers to the current frame config being processed inside |
| 168 | ;; `frame--restore-frames' and its auxiliary functions (like filtering). | 209 | ;; `frameset-restore' and its auxiliary functions (like filtering). |
| 169 | ;; If nil, there is no need to change the display. | 210 | ;; If nil, there is no need to change the display. |
| 170 | ;; If non-nil, display parameter to use when creating the frame. | 211 | ;; If non-nil, display parameter to use when creating the frame. |
| 171 | "Internal use only.") | 212 | "Internal use only.") |
| @@ -191,30 +232,42 @@ Only meaningful when called from a filtering function in | |||
| 191 | (null (cdr frameset--target-display)))) ; to a tty | 232 | (null (cdr frameset--target-display)))) ; to a tty |
| 192 | 233 | ||
| 193 | (defun frameset-filter-tty-to-GUI (_current _filtered parameters saving) | 234 | (defun frameset-filter-tty-to-GUI (_current _filtered parameters saving) |
| 194 | "Remove CURRENT when switching from tty to a graphic display." | 235 | "Remove CURRENT when switching from tty to a graphic display. |
| 236 | |||
| 237 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 238 | see the docstring of `frameset-filter-alist'." | ||
| 195 | (or saving | 239 | (or saving |
| 196 | (not (frameset-switch-to-gui-p parameters)))) | 240 | (not (frameset-switch-to-gui-p parameters)))) |
| 197 | 241 | ||
| 198 | (defun frameset-filter-sanitize-color (current _filtered parameters saving) | 242 | (defun frameset-filter-sanitize-color (current _filtered parameters saving) |
| 199 | "When switching to a GUI frame, remove \"unspecified\" colors. | 243 | "When switching to a GUI frame, remove \"unspecified\" colors. |
| 200 | Useful as a filter function for tty-specific parameters." | 244 | Useful as a filter function for tty-specific parameters. |
| 245 | |||
| 246 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 247 | see the docstring of `frameset-filter-alist'." | ||
| 201 | (or saving | 248 | (or saving |
| 202 | (not (frameset-switch-to-gui-p parameters)) | 249 | (not (frameset-switch-to-gui-p parameters)) |
| 203 | (not (stringp (cdr current))) | 250 | (not (stringp (cdr current))) |
| 204 | (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) | 251 | (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) |
| 205 | 252 | ||
| 206 | (defun frameset-filter-minibuffer (current _filtered _parameters saving) | 253 | (defun frameset-filter-minibuffer (current _filtered _parameters saving) |
| 207 | "When saving, convert (minibuffer . #<window>) parameter to (minibuffer . t)." | 254 | "When saving, convert (minibuffer . #<window>) parameter to (minibuffer . t). |
| 255 | |||
| 256 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 257 | see the docstring of `frameset-filter-alist'." | ||
| 208 | (or (not saving) | 258 | (or (not saving) |
| 209 | (if (windowp (cdr current)) | 259 | (if (windowp (cdr current)) |
| 210 | '(minibuffer . t) | 260 | '(minibuffer . t) |
| 211 | t))) | 261 | t))) |
| 212 | 262 | ||
| 213 | (defun frameset-filter-save-parm (current _filtered parameters saving | 263 | (defun frameset-filter-save-param (current _filtered parameters saving |
| 214 | &optional prefix) | 264 | &optional prefix) |
| 215 | "When switching to a tty frame, save parameter P as PREFIX:P. | 265 | "When switching to a tty frame, save parameter P as PREFIX:P. |
| 216 | The parameter can be later restored with `frameset-filter-restore-parm'. | 266 | The parameter can be later restored with `frameset-filter-restore-param'. |
| 217 | PREFIX defaults to `GUI'." | 267 | PREFIX defaults to `GUI'. |
| 268 | |||
| 269 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 270 | see the docstring of `frameset-filter-alist'." | ||
| 218 | (unless prefix (setq prefix 'GUI)) | 271 | (unless prefix (setq prefix 'GUI)) |
| 219 | (cond (saving t) | 272 | (cond (saving t) |
| 220 | ((frameset-switch-to-tty-p parameters) | 273 | ((frameset-switch-to-tty-p parameters) |
| @@ -226,9 +279,12 @@ PREFIX defaults to `GUI'." | |||
| 226 | (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) | 279 | (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) |
| 227 | (t t))) | 280 | (t t))) |
| 228 | 281 | ||
| 229 | (defun frameset-filter-restore-parm (current filtered parameters saving) | 282 | (defun frameset-filter-restore-param (current filtered parameters saving) |
| 230 | "When switching to a GUI frame, restore PREFIX:P parameter as P. | 283 | "When switching to a GUI frame, restore PREFIX:P parameter as P. |
| 231 | CURRENT must be of the form (PREFIX:P . value)." | 284 | CURRENT must be of the form (PREFIX:P . value). |
| 285 | |||
| 286 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 287 | see the docstring of `frameset-filter-alist'." | ||
| 232 | (or saving | 288 | (or saving |
| 233 | (not (frameset-switch-to-gui-p parameters)) | 289 | (not (frameset-switch-to-gui-p parameters)) |
| 234 | (let* ((prefix:p (symbol-name (car current))) | 290 | (let* ((prefix:p (symbol-name (car current))) |
| @@ -243,9 +299,12 @@ CURRENT must be of the form (PREFIX:P . value)." | |||
| 243 | 299 | ||
| 244 | (defun frameset-filter-iconified (_current _filtered parameters saving) | 300 | (defun frameset-filter-iconified (_current _filtered parameters saving) |
| 245 | "Remove CURRENT when saving an iconified frame. | 301 | "Remove CURRENT when saving an iconified frame. |
| 246 | This is used for positions parameters `left' and `top', which are | 302 | This is used for positional parameters `left' and `top', which are |
| 247 | meaningless in an iconified frame, so the frame is restored in a | 303 | meaningless in an iconified frame, so the frame is restored in a |
| 248 | default position." | 304 | default position. |
| 305 | |||
| 306 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | ||
| 307 | see the docstring of `frameset-filter-alist'." | ||
| 249 | (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) | 308 | (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) |
| 250 | 309 | ||
| 251 | (defun frameset-filter-params (parameters filter-alist saving) | 310 | (defun frameset-filter-params (parameters filter-alist saving) |
| @@ -259,11 +318,11 @@ nil while the filtering is done to restore it." | |||
| 259 | (pcase (cdr (assq (car current) filter-alist)) | 318 | (pcase (cdr (assq (car current) filter-alist)) |
| 260 | (`nil | 319 | (`nil |
| 261 | (push current filtered)) | 320 | (push current filtered)) |
| 262 | (`t | 321 | (:never |
| 263 | nil) | 322 | nil) |
| 264 | (:save | ||
| 265 | (unless saving (push current filtered))) | ||
| 266 | (:restore | 323 | (:restore |
| 324 | (unless saving (push current filtered))) | ||
| 325 | (:save | ||
| 267 | (when saving (push current filtered))) | 326 | (when saving (push current filtered))) |
| 268 | ((or `(,fun . ,args) (and fun (pred fboundp))) | 327 | ((or `(,fun . ,args) (and fun (pred fboundp))) |
| 269 | (let ((this (apply fun current filtered parameters saving args))) | 328 | (let ((this (apply fun current filtered parameters saving args))) |
| @@ -313,7 +372,7 @@ FRAME-LIST is a list of frames. Internal use only." | |||
| 313 | (let* ((mb-frame (window-frame (minibuffer-window frame))) | 372 | (let* ((mb-frame (window-frame (minibuffer-window frame))) |
| 314 | (id (and mb-frame (frame-parameter mb-frame 'frameset--id)))) | 373 | (id (and mb-frame (frame-parameter mb-frame 'frameset--id)))) |
| 315 | (if (null id) | 374 | (if (null id) |
| 316 | (error "Minibuffer frame %S for %S is excluded" mb-frame frame) | 375 | (error "Minibuffer frame %S for %S is not being saved" mb-frame frame) |
| 317 | ;; For minibufferless frames, frameset--mini is a cons | 376 | ;; For minibufferless frames, frameset--mini is a cons |
| 318 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id | 377 | ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id |
| 319 | ;; of the frame containing its minibuffer window. | 378 | ;; of the frame containing its minibuffer window. |
| @@ -329,27 +388,29 @@ FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. | |||
| 329 | PREDICATE is a predicate function, which must return non-nil for frames that | 388 | PREDICATE is a predicate function, which must return non-nil for frames that |
| 330 | should be saved; it defaults to saving all frames from FRAME-LIST. | 389 | should be saved; it defaults to saving all frames from FRAME-LIST. |
| 331 | PROPERTIES is a user-defined property list to add to the frameset." | 390 | PROPERTIES is a user-defined property list to add to the frameset." |
| 332 | (let ((frames (cl-delete-if-not #'frame-live-p | 391 | (let* ((list (or (copy-sequence frame-list) (frame-list))) |
| 333 | (cl-delete-if-not (or predicate #'framep) | 392 | (frames (cl-delete-if-not #'frame-live-p |
| 334 | (or (copy-sequence frame-list) | 393 | (if predicate |
| 335 | (frame-list)))))) | 394 | (cl-delete-if-not predicate list) |
| 395 | list)))) | ||
| 336 | (frameset--process-minibuffer-frames frames) | 396 | (frameset--process-minibuffer-frames frames) |
| 337 | (make-frameset :properties (append '(:version 1) properties) | 397 | (make-frameset properties |
| 338 | :states (mapcar | 398 | (mapcar |
| 339 | (lambda (frame) | 399 | (lambda (frame) |
| 340 | (cons | 400 | (cons |
| 341 | (frameset-filter-params (frame-parameters frame) | 401 | (frameset-filter-params (frame-parameters frame) |
| 342 | (or filters | 402 | (or filters frameset-filter-alist) |
| 343 | frameset-filter-alist) | 403 | t) |
| 344 | t) | 404 | (window-state-get (frame-root-window frame) t))) |
| 345 | (window-state-get (frame-root-window frame) t))) | 405 | frames)))) |
| 346 | frames)))) | ||
| 347 | 406 | ||
| 348 | 407 | ||
| 349 | ;; Restoring framesets | 408 | ;; Restoring framesets |
| 350 | 409 | ||
| 351 | (defvar frameset--reuse-list nil | 410 | (defvar frameset--reuse-list nil |
| 352 | "Internal use only.") | 411 | "The list of frames potentially reusable. |
| 412 | Its value is only meaningful during execution of `frameset-restore'. | ||
| 413 | Internal use only.") | ||
| 353 | 414 | ||
| 354 | (defun frameset--compute-pos (value left/top right/bottom) | 415 | (defun frameset--compute-pos (value left/top right/bottom) |
| 355 | (pcase value | 416 | (pcase value |
| @@ -494,11 +555,11 @@ Internal use only." | |||
| 494 | (cl-loop for param in '(left top with height border-width minibuffer) | 555 | (cl-loop for param in '(left top with height border-width minibuffer) |
| 495 | collect (assq param frame-cfg))) | 556 | collect (assq param frame-cfg))) |
| 496 | 557 | ||
| 497 | (defun frameset--get-frame (frame-cfg window-cfg filters force-onscreen) | 558 | (defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) |
| 498 | "Set up and return a frame according to its saved state. | 559 | "Set up and return a frame according to its saved state. |
| 499 | That means either reusing an existing frame or creating one anew. | 560 | That means either reusing an existing frame or creating one anew. |
| 500 | FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state. | 561 | FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state. |
| 501 | For the meaning of FORCE-ONSCREEN, see `frameset-restore'. | 562 | For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. |
| 502 | Internal use only." | 563 | Internal use only." |
| 503 | (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) | 564 | (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) |
| 504 | (lines (assq 'tool-bar-lines frame-cfg)) | 565 | (lines (assq 'tool-bar-lines frame-cfg)) |
| @@ -563,7 +624,7 @@ Internal use only." | |||
| 563 | (window-state-put window-cfg (frame-root-window frame) 'safe) | 624 | (window-state-put window-cfg (frame-root-window frame) 'safe) |
| 564 | frame)) | 625 | frame)) |
| 565 | 626 | ||
| 566 | (defun frameset--sort-states (state1 state2) | 627 | (defun frameset--minibufferless-last-p (state1 state2) |
| 567 | "Predicate to sort frame states in a suitable order to be created. | 628 | "Predicate to sort frame states in a suitable order to be created. |
| 568 | It sorts minibuffer-owning frames before minibufferless ones." | 629 | It sorts minibuffer-owning frames before minibufferless ones." |
| 569 | (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1))) | 630 | (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1))) |
| @@ -580,10 +641,8 @@ It sorts minibuffer-owning frames before minibufferless ones." | |||
| 580 | ((eq system-type 'windows-nt) nil) | 641 | ((eq system-type 'windows-nt) nil) |
| 581 | (t (not force-display)))) | 642 | (t (not force-display)))) |
| 582 | 643 | ||
| 583 | (defun frameset-sort-frames-for-deletion (frame1 _frame2) | 644 | (defun frameset-minibufferless-first-p (frame1 _frame2) |
| 584 | "Predicate to sort live frames for deletion. | 645 | "Predicate to sort minibufferless frames before other frames." |
| 585 | Minibufferless frames must go first to avoid errors when attempting | ||
| 586 | to delete a frame whose minibuffer window is used by another frame." | ||
| 587 | (not (frame-parameter frame1 'minibuffer))) | 646 | (not (frame-parameter frame1 'minibuffer))) |
| 588 | 647 | ||
| 589 | ;;;###autoload | 648 | ;;;###autoload |
| @@ -593,31 +652,31 @@ to delete a frame whose minibuffer window is used by another frame." | |||
| 593 | 652 | ||
| 594 | FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. | 653 | FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. |
| 595 | 654 | ||
| 596 | REUSE-FRAMES describes how to reuse existing frames while restoring a frameset: | 655 | REUSE-FRAMES selects the policy to use to reuse frames when restoring: |
| 597 | t Reuse any existing frame if possible; delete leftover frames. | 656 | t Reuse any existing frame if possible; delete leftover frames. |
| 598 | nil Restore frameset in new frames and delete existing frames. | 657 | nil Restore frameset in new frames and delete existing frames. |
| 599 | :keep Restore frameset in new frames and keep the existing ones. | 658 | :keep Restore frameset in new frames and keep the existing ones. |
| 600 | LIST A list of frames to reuse; only these will be reused, if possible, | 659 | LIST A list of frames to reuse; only these are reused (if possible), |
| 601 | and any leftover one will be deleted; other frames not on this | 660 | and any leftover ones are deleted; other frames not on this |
| 602 | list will be kept. | 661 | list are left untouched. |
| 603 | 662 | ||
| 604 | FORCE-DISPLAY can be: | 663 | FORCE-DISPLAY can be: |
| 605 | t Frames will be restored in the current display. | 664 | t Frames are restored in the current display. |
| 606 | nil Frames will be restored, if possible, in their original displays. | 665 | nil Frames are restored, if possible, in their original displays. |
| 607 | :delete Frames in other displays will be deleted instead of restored. | 666 | :delete Frames in other displays are deleted instead of restored. |
| 608 | PRED A function which will be called with one argument, the parameter | 667 | PRED A function called with one argument, the parameter list; |
| 609 | list, and must return t, nil or `:delete', as above but affecting | 668 | it must return t, nil or `:delete', as above but affecting |
| 610 | only the frame that will be created from that parameter list. | 669 | only the frame that will be created from that parameter list. |
| 611 | 670 | ||
| 612 | FORCE-ONSCREEN can be: | 671 | FORCE-ONSCREEN can be: |
| 613 | :all Force onscreen any frame fully or partially offscreen. | ||
| 614 | t Force onscreen only those frames that are fully offscreen. | 672 | t Force onscreen only those frames that are fully offscreen. |
| 615 | nil Do not force any frame back onscreen. | 673 | nil Do not force any frame back onscreen. |
| 616 | PRED A function which will be called with three arguments, | 674 | :all Force onscreen any frame fully or partially offscreen. |
| 675 | PRED A function called with three arguments, | ||
| 617 | - the live frame just restored, | 676 | - the live frame just restored, |
| 618 | - a list (LEFT TOP WIDTH HEIGHT), describing the frame, | 677 | - a list (LEFT TOP WIDTH HEIGHT), describing the frame, |
| 619 | - a list (LEFT TOP WIDTH HEIGHT), describing the workarea, | 678 | - a list (LEFT TOP WIDTH HEIGHT), describing the workarea. |
| 620 | and must return non-nil to force the frame onscreen, nil otherwise. | 679 | It must return non-nil to force the frame onscreen, nil otherwise. |
| 621 | 680 | ||
| 622 | Note the timing and scope of the operations described above: REUSE-FRAMES | 681 | Note the timing and scope of the operations described above: REUSE-FRAMES |
| 623 | affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being | 682 | affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being |
| @@ -648,7 +707,7 @@ All keywords default to nil." | |||
| 648 | ;; Sort saved states to guarantee that minibufferless frames will be created | 707 | ;; Sort saved states to guarantee that minibufferless frames will be created |
| 649 | ;; after the frames that contain their minibuffer windows. | 708 | ;; after the frames that contain their minibuffer windows. |
| 650 | (dolist (state (sort (copy-sequence (frameset-states frameset)) | 709 | (dolist (state (sort (copy-sequence (frameset-states frameset)) |
| 651 | #'frameset--sort-states)) | 710 | #'frameset--minibufferless-last-p)) |
| 652 | (condition-case-unless-debug err | 711 | (condition-case-unless-debug err |
| 653 | (pcase-let* ((`(,frame-cfg . ,window-cfg) state) | 712 | (pcase-let* ((`(,frame-cfg . ,window-cfg) state) |
| 654 | ((and d-mini `(,hasmini . ,mb-id)) | 713 | ((and d-mini `(,hasmini . ,mb-id)) |
| @@ -716,9 +775,9 @@ All keywords default to nil." | |||
| 716 | (push (cons 'minibuffer mb-window) frame-cfg))))) | 775 | (push (cons 'minibuffer mb-window) frame-cfg))))) |
| 717 | ;; OK, we're ready at last to create (or reuse) a frame and | 776 | ;; OK, we're ready at last to create (or reuse) a frame and |
| 718 | ;; restore the window config. | 777 | ;; restore the window config. |
| 719 | (setq frame (frameset--get-frame frame-cfg window-cfg | 778 | (setq frame (frameset--restore-frame frame-cfg window-cfg |
| 720 | (or filters frameset-filter-alist) | 779 | (or filters frameset-filter-alist) |
| 721 | force-onscreen)) | 780 | force-onscreen)) |
| 722 | ;; Set default-minibuffer if required. | 781 | ;; Set default-minibuffer if required. |
| 723 | (when default (setq default-minibuffer-frame frame)))) | 782 | (when default (setq default-minibuffer-frame frame)))) |
| 724 | (error | 783 | (error |
| @@ -732,7 +791,10 @@ All keywords default to nil." | |||
| 732 | (unless (eq reuse-frames :keep) | 791 | (unless (eq reuse-frames :keep) |
| 733 | (dolist (frame (sort (nconc (if (listp reuse-frames) nil other-frames) | 792 | (dolist (frame (sort (nconc (if (listp reuse-frames) nil other-frames) |
| 734 | frameset--reuse-list) | 793 | frameset--reuse-list) |
| 735 | #'frameset-sort-frames-for-deletion)) | 794 | ;; Minibufferless frames must go first to avoid |
| 795 | ;; errors when attempting to delete a frame whose | ||
| 796 | ;; minibuffer window is used by another frame. | ||
| 797 | #'frameset-minibufferless-first-p)) | ||
| 736 | (condition-case err | 798 | (condition-case err |
| 737 | (delete-frame frame) | 799 | (delete-frame frame) |
| 738 | (error | 800 | (error |