diff options
| author | Juanma Barranquero | 2013-08-08 00:54:08 +0200 |
|---|---|---|
| committer | Juanma Barranquero | 2013-08-08 00:54:08 +0200 |
| commit | a912c0163d1f6fac4d443522b712169c6d31b523 (patch) | |
| tree | f2cf8b99817c8357daa114b288d57238142f8d70 | |
| parent | f001e98ec5cc0d145a324f2d4062adbe44c16060 (diff) | |
| download | emacs-a912c0163d1f6fac4d443522b712169c6d31b523.tar.gz emacs-a912c0163d1f6fac4d443522b712169c6d31b523.zip | |
lisp/frameset.el: Convert `frameset' to vector and add new slots.
(frameset): Use type vector, not list (incompatible change).
Do not declare a new constructor, use the default one.
Upgrade suggested properties `app', `name' and `desc' to slots `app',
`name' and `description', respectively, and add read-only slot `timestamp'.
Doc fixes.
(frameset-copy, frameset-persistent-filter-alist)
(frameset-filter-alist, frameset-switch-to-gui-p)
(frameset-switch-to-tty-p, frameset-filter-tty-to-GUI)
(frameset-filter-sanitize-color, frameset-filter-minibuffer)
(frameset-filter-iconified, frameset-keep-original-display-p):
Doc fixes.
(frameset-filter-shelve-param, frameset-filter-unshelve-param):
Rename from frameset-filter-(save|restore)-param. All callers changed.
Doc fix.
(frameset-p): Adapt to change to vector and be more thorough.
Change arg name to OBJECT. Doc fix.
(frameset-prop): Rename arg PROP to PROPERTY. Doc fix.
(frameset-session-filter-alist): Rename from frameset-live-filter-alist.
All callers changed.
(frameset-frame-with-id): Rename from frameset-locate-frame-id.
All callers changed.
(frameset--record-minibuffer-relationships): Rename from
frameset--process-minibuffer-frames. All callers changed.
(frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION.
Use new default constructor (again). Doc fix.
(frameset--find-frame-if): Rename from `frameset--find-frame.
All callers changed.
(frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS.
(frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS.
Doc fix.
(frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to
PARAMETERS and WINDOW-STATE, respectively.
(frameset-restore): Add new keyword argument PREDICATE.
Reset frameset--target-display to nil. Doc fix.
lisp/desktop.el (desktop-save-frameset): Use new frameset-save args.
Use lexical-binding.
| -rw-r--r-- | lisp/ChangeLog | 40 | ||||
| -rw-r--r-- | lisp/desktop.el | 12 | ||||
| -rw-r--r-- | lisp/frameset.el | 667 |
3 files changed, 518 insertions, 201 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 20c20097532..93c10d858e7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,43 @@ | |||
| 1 | 2013-08-07 Juanma Barranquero <lekktu@gmail.com> | ||
| 2 | |||
| 3 | * desktop.el (desktop-save-frameset): Use new frameset-save args. | ||
| 4 | Use lexical-binding. | ||
| 5 | |||
| 6 | * frameset.el (frameset): Use type vector, not list (incompatible | ||
| 7 | change). Do not declare a new constructor, use the default one. | ||
| 8 | Upgrade suggested properties `app', `name' and `desc' to slots `app', | ||
| 9 | `name' and `description', respectively, and add read-only slot | ||
| 10 | `timestamp'. Doc fixes. | ||
| 11 | (frameset-copy, frameset-persistent-filter-alist) | ||
| 12 | (frameset-filter-alist, frameset-switch-to-gui-p) | ||
| 13 | (frameset-switch-to-tty-p, frameset-filter-tty-to-GUI) | ||
| 14 | (frameset-filter-sanitize-color, frameset-filter-minibuffer) | ||
| 15 | (frameset-filter-iconified, frameset-keep-original-display-p): | ||
| 16 | Doc fixes. | ||
| 17 | (frameset-filter-shelve-param, frameset-filter-unshelve-param): | ||
| 18 | Rename from frameset-filter-(save|restore)-param. All callers changed. | ||
| 19 | Doc fix. | ||
| 20 | (frameset-p): Adapt to change to vector and be more thorough. | ||
| 21 | Change arg name to OBJECT. Doc fix. | ||
| 22 | (frameset-prop): Rename arg PROP to PROPERTY. Doc fix. | ||
| 23 | (frameset-session-filter-alist): Rename from frameset-live-filter-alist. | ||
| 24 | All callers changed. | ||
| 25 | (frameset-frame-with-id): Rename from frameset-locate-frame-id. | ||
| 26 | All callers changed. | ||
| 27 | (frameset--record-minibuffer-relationships): Rename from | ||
| 28 | frameset--process-minibuffer-frames. All callers changed. | ||
| 29 | (frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION. | ||
| 30 | Use new default constructor (again). Doc fix. | ||
| 31 | (frameset--find-frame-if): Rename from `frameset--find-frame. | ||
| 32 | All callers changed. | ||
| 33 | (frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS. | ||
| 34 | (frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS. | ||
| 35 | Doc fix. | ||
| 36 | (frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to | ||
| 37 | PARAMETERS and WINDOW-STATE, respectively. | ||
| 38 | (frameset-restore): Add new keyword argument PREDICATE. | ||
| 39 | Reset frameset--target-display to nil. Doc fix. | ||
| 40 | |||
| 1 | 2013-08-07 Stefan Monnier <monnier@iro.umontreal.ca> | 41 | 2013-08-07 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 42 | ||
| 3 | * progmodes/bat-mode.el (bat--syntax-propertize): New var. | 43 | * progmodes/bat-mode.el (bat--syntax-propertize): New var. |
diff --git a/lisp/desktop.el b/lisp/desktop.el index 76aa30e4090..91635218228 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; desktop.el --- save partial status of Emacs when killed | 1 | ;;; desktop.el --- save partial status of Emacs when killed -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1993-1995, 1997, 2000-2013 Free Software Foundation, | 3 | ;; Copyright (C) 1993-1995, 1997, 2000-2013 Free Software Foundation, |
| 4 | ;; Inc. | 4 | ;; Inc. |
| @@ -910,12 +910,10 @@ DIRNAME must be the directory in which the desktop file will be saved." | |||
| 910 | Frames with a non-nil `desktop-dont-save' parameter are not saved." | 910 | Frames with a non-nil `desktop-dont-save' parameter are not saved." |
| 911 | (setq desktop-saved-frameset | 911 | (setq desktop-saved-frameset |
| 912 | (and desktop-restore-frames | 912 | (and desktop-restore-frames |
| 913 | (let ((name (concat user-login-name "@" system-name | 913 | (frameset-save nil |
| 914 | (format-time-string " %Y-%m-%d %T")))) | 914 | :app desktop--app-id |
| 915 | (frameset-save nil | 915 | :name (concat user-login-name "@" system-name) |
| 916 | :predicate #'desktop--check-dont-save | 916 | :predicate #'desktop--check-dont-save)))) |
| 917 | :properties (list :app desktop--app-id | ||
| 918 | :name name)))))) | ||
| 919 | 917 | ||
| 920 | ;;;###autoload | 918 | ;;;###autoload |
| 921 | (defun desktop-save (dirname &optional release auto-save) | 919 | (defun desktop-save (dirname &optional release auto-save) |
diff --git a/lisp/frameset.el b/lisp/frameset.el index 45cf86eb3cc..ad58a17c840 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el | |||
| @@ -41,41 +41,35 @@ | |||
| 41 | (require 'cl-lib) | 41 | (require 'cl-lib) |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | (cl-defstruct (frameset (:type list) :named | 44 | (cl-defstruct (frameset (:type vector) :named |
| 45 | ;; Copier and predicate functions are defined below. | 45 | ;; Copier and predicate functions are defined below. |
| 46 | (:copier nil) | 46 | (:copier nil) |
| 47 | (:predicate nil) | 47 | (:predicate nil)) |
| 48 | ;; A BOA constructor, not the default "keywordy" one. | ||
| 49 | ;; This is for internal use; to create a frameset, | ||
| 50 | ;; the "right" way to do it is with frameset-save. | ||
| 51 | (:constructor make-frameset (properties states))) | ||
| 52 | 48 | ||
| 53 | "A frameset encapsulates a serializable view of a set of frames and windows. | 49 | "A frameset encapsulates a serializable view of a set of frames and windows. |
| 54 | 50 | ||
| 55 | It contains the following slots, which can be accessed with | 51 | It contains the following slots, which can be accessed with |
| 56 | \(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): | 52 | \(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): |
| 57 | 53 | ||
| 58 | version A non-modifiable version number, identifying the format | 54 | version A read-only version number, identifying the format |
| 59 | of the frameset struct. Currently its value is 1. | 55 | of the frameset struct. Currently its value is 1. |
| 56 | timestamp A read-only timestamp, the output of `current-time'. | ||
| 57 | app A symbol, or a list whose first element is a symbol, which | ||
| 58 | identifies the creator of the frameset and related info; | ||
| 59 | for example, desktop.el sets this slot to a list | ||
| 60 | `(desktop . ,desktop-file-version). | ||
| 61 | name A string, the name of the frameset instance. | ||
| 62 | description A string, a description for user consumption (to show in | ||
| 63 | menus, messages, etc). | ||
| 60 | properties A property list, to store both frameset-specific and | 64 | properties A property list, to store both frameset-specific and |
| 61 | user-defined serializable data (see suggestions below). | 65 | user-defined serializable data. |
| 62 | states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no | 66 | states A list of items (FRAME-PARAMETERS . WINDOW-STATE), in no |
| 63 | particular order. Each item represents a frame to be | 67 | particular order. Each item represents a frame to be |
| 64 | restored. FRAME-PARAMETERS is a frame's parameter alist, | 68 | restored. FRAME-PARAMETERS is a frame's parameter alist, |
| 65 | extracted with (frame-parameters FRAME) and filtered through | 69 | extracted with (frame-parameters FRAME) and filtered |
| 66 | `frame-parameters-alist' or a similar filter alist. | 70 | through `frameset-filter-params'. |
| 67 | WINDOW-STATE is the output of `window-state-get', when | 71 | WINDOW-STATE is the output of `window-state-get' applied |
| 68 | applied to the root window of the frame. | 72 | to the root window of the frame. |
| 69 | |||
| 70 | Some suggested properties: | ||
| 71 | |||
| 72 | :app APPINFO Can be used by applications and packages to indicate the | ||
| 73 | intended (but by no means exclusive) use of the frameset. | ||
| 74 | Freeform. For example, currently desktop.el framesets set | ||
| 75 | :app to `(desktop . ,desktop-file-version). | ||
| 76 | :name NAME The name of the frameset instance; a string. | ||
| 77 | :desc TEXT A description for user consumption (to show in a menu to | ||
| 78 | choose among framesets, etc.); a string. | ||
| 79 | 73 | ||
| 80 | To avoid collisions, it is recommended that applications wanting to add | 74 | To avoid collisions, it is recommended that applications wanting to add |
| 81 | private serializable data to `properties' either store all info under a | 75 | private serializable data to `properties' either store all info under a |
| @@ -95,31 +89,41 @@ A frameset is intended to be used through the following simple API: | |||
| 95 | `properties' slot. | 89 | `properties' slot. |
| 96 | - The `frameset-SLOT' accessors described above." | 90 | - The `frameset-SLOT' accessors described above." |
| 97 | 91 | ||
| 98 | (version 1 :read-only t) | 92 | (version 1 :read-only t) |
| 99 | properties states) | 93 | (timestamp (current-time) :read-only t) |
| 94 | (app nil) | ||
| 95 | (name nil) | ||
| 96 | (description nil) | ||
| 97 | (properties nil) | ||
| 98 | (states nil)) | ||
| 100 | 99 | ||
| 101 | (defun frameset-copy (frameset) | 100 | (defun frameset-copy (frameset) |
| 102 | "Return a copy of FRAMESET. | 101 | "Return a deep copy of FRAMESET. |
| 103 | This is a deep copy done with `copy-tree'." | 102 | FRAMESET is copied with `copy-tree'." |
| 104 | (copy-tree frameset t)) | 103 | (copy-tree frameset t)) |
| 105 | 104 | ||
| 106 | ;;;###autoload | 105 | ;;;###autoload |
| 107 | (defun frameset-p (frameset) | 106 | (defun frameset-p (object) |
| 108 | "If FRAMESET is a frameset, return its version number. | 107 | "If OBJECT is a frameset, return its version number. |
| 109 | Else return nil." | 108 | Else return nil." |
| 110 | (and (eq (car-safe frameset) 'frameset) ; is a list | 109 | (and (vectorp object) ; a vector |
| 111 | (integerp (nth 1 frameset)) ; version is an int | 110 | (eq (aref object 0) 'frameset) ; tagged as `frameset' |
| 112 | (nth 3 frameset) ; states is non-null | 111 | (integerp (aref object 1)) ; version is an int |
| 113 | (nth 1 frameset))) ; return version | 112 | (consp (aref object 2)) ; timestamp is a non-null list |
| 113 | (stringp (or (aref object 4) "")) ; name is a string or null | ||
| 114 | (stringp (or (aref object 5) "")) ; description is a string or null | ||
| 115 | (listp (aref object 6)) ; properties is a list | ||
| 116 | (consp (aref object 7)) ; and states is non-null | ||
| 117 | (aref object 1))) ; return version | ||
| 114 | 118 | ||
| 115 | ;; A setf'able accessor to the frameset's properties | 119 | ;; A setf'able accessor to the frameset's properties |
| 116 | (defun frameset-prop (frameset prop) | 120 | (defun frameset-prop (frameset property) |
| 117 | "Return the value of the PROP property of FRAMESET. | 121 | "Return the value for FRAMESET of PROPERTY. |
| 118 | 122 | ||
| 119 | Properties can be set with | 123 | Properties can be set with |
| 120 | 124 | ||
| 121 | (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" | 125 | (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" |
| 122 | (plist-get (frameset-properties frameset) prop)) | 126 | (plist-get (frameset-properties frameset) property)) |
| 123 | 127 | ||
| 124 | (gv-define-setter frameset-prop (val fs prop) | 128 | (gv-define-setter frameset-prop (val fs prop) |
| 125 | (macroexp-let2 nil v val | 129 | (macroexp-let2 nil v val |
| @@ -131,8 +135,261 @@ Properties can be set with | |||
| 131 | 135 | ||
| 132 | ;; Filtering | 136 | ;; Filtering |
| 133 | 137 | ||
| 138 | ;; What's the deal with these "filter alists"? | ||
| 139 | ;; | ||
| 140 | ;; Let's say that Emacs' frame parameters were never designed as a tool to | ||
| 141 | ;; precisely record (or restore) a frame's state. They grew organically, | ||
| 142 | ;; and their uses and behaviors reflect their history. In using them to | ||
| 143 | ;; implement framesets, the unwary implementor, or the prospective package | ||
| 144 | ;; writer willing to use framesets in their code, might fall victim of some | ||
| 145 | ;; unexpected... oddities. | ||
| 146 | ;; | ||
| 147 | ;; You can find frame parameters that: | ||
| 148 | ;; | ||
| 149 | ;; - can be used to get and set some data from the frame's current state | ||
| 150 | ;; (`height', `width') | ||
| 151 | ;; - can be set at creation time, and setting them afterwards has no effect | ||
| 152 | ;; (`window-state', `minibuffer') | ||
| 153 | ;; - can be set at creation time, and setting them afterwards will fail with | ||
| 154 | ;; an error, *unless* you set it to the same value, a noop (`border-width') | ||
| 155 | ;; - act differently when passed at frame creation time, and when set | ||
| 156 | ;; afterwards (`height') | ||
| 157 | ;; - affect the value of other parameters (`name', `visibility') | ||
| 158 | ;; - can be ignored by window managers (most positional args, like `height', | ||
| 159 | ;; `width', `left' and `top', and others, like `auto-raise', `auto-lower') | ||
| 160 | ;; - can be set externally in X resources or Window registry (again, most | ||
| 161 | ;; positional parameters, and also `toolbar-lines', `menu-bar-lines' etc.) | ||
| 162 | ;, - can contain references to live objects (`buffer-list', `minibuffer') or | ||
| 163 | ;; code (`buffer-predicate') | ||
| 164 | ;; - are set automatically, and cannot be changed (`window-id', `parent-id'), | ||
| 165 | ;; but setting them produces no error | ||
| 166 | ;; - have a noticeable effect in some window managers, and are ignored in | ||
| 167 | ;; others (`menu-bar-lines') | ||
| 168 | ;; - can not be safely set in a tty session and then copied back to a GUI | ||
| 169 | ;; session (`font', `background-color', `foreground-color') | ||
| 170 | ;; | ||
| 171 | ;; etc etc. | ||
| 172 | ;; | ||
| 173 | ;; Which means that, in order to save a parameter alist to disk and read it | ||
| 174 | ;; back later to reconstruct a frame, some processing must be done. That's | ||
| 175 | ;; what `frameset-filter-params' and the `frameset-*-filter-alist' variables | ||
| 176 | ;; are for. | ||
| 177 | ;; | ||
| 178 | ;; First, a clarification: the word "filter" in these names refers to both | ||
| 179 | ;; common meanings of filter: to filter out (i.e., to remove), and to pass | ||
| 180 | ;; through a transformation function (think `filter-buffer-substring'). | ||
| 181 | ;; | ||
| 182 | ;; `frameset-filter-params' takes a parameter alist PARAMETERS, a filtering | ||
| 183 | ;; alist FILTER-ALIST, and a flag SAVING to indicate whether we are filtering | ||
| 184 | ;; parameters with the intent of saving a frame or restoring it. It then | ||
| 185 | ;; accumulates an output list, FILTERED, by checking each parameter in | ||
| 186 | ;; PARAMETERS against FILTER-ALIST and obeying any rule found there. The | ||
| 187 | ;; absence of a rule just means the parameter/value pair (called CURRENT in | ||
| 188 | ;; filtering functions) is copied to FILTERED as is. Keyword values :save, | ||
| 189 | ;; :restore and :never tell the function to copy CURRENT to FILTERED in the | ||
| 190 | ;; respective situations, that is, when saving, restoring, or never at all. | ||
| 191 | ;; Values :save and :restore are not used in this package, because usually if | ||
| 192 | ;; you don't want to save a parameter, you don't want to restore it either. | ||
| 193 | ;; But they can be useful, for example, if you already have a saved frameset | ||
| 194 | ;; created with some intent, and want to reuse it for a different objective | ||
| 195 | ;; where the expected parameter list has different requirements. | ||
| 196 | ;; | ||
| 197 | ;; Finally, the value can also be a filtering function, or a filtering | ||
| 198 | ;; function plus some arguments. The function is called for each matching | ||
| 199 | ;; parameter, and receives CURRENT (the parameter/value pair being processed), | ||
| 200 | ;; FILTERED (the output alist so far), PARAMETERS (the full parameter alist), | ||
| 201 | ;; SAVING (the save/restore flag), plus any additional ARGS set along the | ||
| 202 | ;; function in the `frameset-*-filter-alist' entry. The filtering function | ||
| 203 | ;; then has the possibility to pass along CURRENT, or reject it altogether, | ||
| 204 | ;; or pass back a (NEW-PARAM . NEW-VALUE) pair, which does not even need to | ||
| 205 | ;; refer to the same parameter (so you can filter `width' and return `height' | ||
| 206 | ;; and vice versa, if you're feeling silly and want to mess with the user's | ||
| 207 | ;; mind). As a help in deciding what to do, the filtering function has | ||
| 208 | ;; access to PARAMETERS, but must not change it in any way. It also has | ||
| 209 | ;; access to FILTERED, which can be modified at will. This allows two or | ||
| 210 | ;; more filters to coordinate themselves, because in general there's no way | ||
| 211 | ;; to predict the order in which they will be run. | ||
| 212 | ;; | ||
| 213 | ;; So, which parameters are filtered by default, and why? Let's see. | ||
| 214 | ;; | ||
| 215 | ;; - `buffer-list', `buried-buffer-list', `buffer-predicate': They contain | ||
| 216 | ;; references to live objects, or in the case of `buffer-predicate', it | ||
| 217 | ;; could also contain an fbound symbol (a predicate function) that could | ||
| 218 | ;; not be defined in a later session. | ||
| 219 | ;; | ||
| 220 | ;; - `window-id', `outer-window-id', `parent-id': They are assigned | ||
| 221 | ;; automatically and cannot be set, so keeping them is harmless, but they | ||
| 222 | ;; add clutter. `window-system' is similar: it's assigned at frame | ||
| 223 | ;; creation, and does not serve any useful purpose later. | ||
| 224 | ;; | ||
| 225 | ;; - `left', `top': Only problematic when saving an iconified frame, because | ||
| 226 | ;; when the frame is iconified they are set to (- 32000), which doesn't | ||
| 227 | ;; really help in restoring the frame. Better to remove them and let the | ||
| 228 | ;; window manager choose a default position for the frame. | ||
| 229 | ;; | ||
| 230 | ;; - `background-color', `foreground-color': In tty frames they can be set | ||
| 231 | ;; to "unspecified-bg" and "unspecified-fg", which aren't understood on | ||
| 232 | ;; GUI sessions. They have to be filtered out when switching from tty to | ||
| 233 | ;; a graphical display. | ||
| 234 | ;; | ||
| 235 | ;; - `tty', `tty-type': These are tty-specific. When switching to a GUI | ||
| 236 | ;; display they do no harm, but they clutter the parameter list. | ||
| 237 | ;; | ||
| 238 | ;; - `minibuffer': It can contain a reference to a live window, which cannot | ||
| 239 | ;; be serialized. Because of Emacs' idiosyncratic treatment of this | ||
| 240 | ;; parameter, frames created with (minibuffer . t) have a parameter | ||
| 241 | ;; (minibuffer . #<window...>), while frames created with | ||
| 242 | ;; (minibuffer . #<window...>) have (minibuffer . nil), which is madness | ||
| 243 | ;; but helps to differentiate between minibufferless and "normal" frames. | ||
| 244 | ;; So, changing (minibuffer . #<window...>) to (minibuffer . t) allows | ||
| 245 | ;; Emacs to set up the new frame correctly. Nice, uh? | ||
| 246 | ;; | ||
| 247 | ;; - `name': If this parameter is directly set, `explicit-name' is | ||
| 248 | ;; automatically set to t, and then `name' no longer changes dynamically. | ||
| 249 | ;; So, in general, not saving `name' is the right thing to do, though | ||
| 250 | ;; surely there are applications that will want to override this filter. | ||
| 251 | ;; | ||
| 252 | ;; - `font', `fullscreen', `height' and `width': These parameters suffer | ||
| 253 | ;; from the fact that they are badly manged when going through a | ||
| 254 | ;; tty session, though not all in the same way. When saving a GUI frame | ||
| 255 | ;; and restoring it in a tty, the height and width of the new frame are | ||
| 256 | ;; those of the tty screen (let's say 80x25, for example); going back | ||
| 257 | ;; to a GUI session means getting frames of the tty screen size (so all | ||
| 258 | ;; your frames are 80 cols x 25 rows). For `fullscreen' there's a | ||
| 259 | ;; similar problem, because a tty frame cannot really be fullscreen or | ||
| 260 | ;; maximized, so the state is lost. The problem with `font' is a bit | ||
| 261 | ;; different, because a valid GUI font spec in `font' turns into | ||
| 262 | ;; (font . "tty") in a tty frame, and when read back into a GUI session | ||
| 263 | ;; it fails because `font's value is no longer a valid font spec. | ||
| 264 | ;; | ||
| 265 | ;; In most cases, the filtering functions just do the obvious thing: remove | ||
| 266 | ;; CURRENT when it is meaningless to keep it, or pass a modified copy if | ||
| 267 | ;; that helps (as in the case of `minibuffer'). | ||
| 268 | ;; | ||
| 269 | ;; The exception are the parameters in the last set, which should survive | ||
| 270 | ;; the roundtrip though tty-land. The answer is to add "stashing | ||
| 271 | ;; parameters", working in pairs, to shelve the GUI-specific contents and | ||
| 272 | ;; restore it once we're back in pixel country. That's what functions | ||
| 273 | ;; `frameset-filter-shelve-param' and `frameset-unshelve-param' do. | ||
| 274 | ;; | ||
| 275 | ;; Basically, if you set `frameset-filter-shelve-param' as the filter for | ||
| 276 | ;; a parameter P, it will detect when it is restoring a GUI frame into a | ||
| 277 | ;; tty session, and save P's value in the custom parameter X:P, but only | ||
| 278 | ;; if X:P does not exist already (so it is not overwritten if you enter | ||
| 279 | ;; the tty session more than once). If you're not switching to a tty | ||
| 280 | ;; frame, the filter just passes CURRENT along. | ||
| 281 | ;; | ||
| 282 | ;; The parameter X:P, on the other hand, must have been setup to be | ||
| 283 | ;; filtered by `frameset-filter-unshelve-param', which unshelves the | ||
| 284 | ;; value: if we're entering a GUI session, returns P instead of CURRENT, | ||
| 285 | ;; while in other cases it just passes it along. | ||
| 286 | ;; | ||
| 287 | ;; The only additional trick is that `frameset-filter-shelve-param' does | ||
| 288 | ;; not set P if switching back to GUI and P already has a value, because | ||
| 289 | ;; it assumes that `frameset-filter-unshelve-param' did set it up. And | ||
| 290 | ;; `frameset-filter-unshelve-param', when unshelving P, must look into | ||
| 291 | ;; FILTERED to determine if P has already been set and if so, modify it; | ||
| 292 | ;; else just returns P. | ||
| 293 | ;; | ||
| 294 | ;; Currently, the value of X in X:P is `GUI', but you can use any prefix, | ||
| 295 | ;; by passing its symbol as argument in the filter: | ||
| 296 | ;; | ||
| 297 | ;; (my-parameter frameset-filter-shelve-param MYPREFIX) | ||
| 298 | ;; | ||
| 299 | ;; instead of | ||
| 300 | ;; | ||
| 301 | ;; (my-parameter . frameset-filter-shelve-param) | ||
| 302 | ;; | ||
| 303 | ;; Note that `frameset-filter-unshelve-param' does not need MYPREFIX | ||
| 304 | ;; because it is available from the parameter name in CURRENT. Also note | ||
| 305 | ;; that the colon between the prefix and the parameter name is hardcoded. | ||
| 306 | ;; The reason is that X:P is quite readable, and that the colon is a | ||
| 307 | ;; very unusual character in symbol names, other than in initial position | ||
| 308 | ;; in keywords (emacs -Q has only two such symbols, and one of them is a | ||
| 309 | ;; URL). So the probability of a collision with existing or future | ||
| 310 | ;; symbols is quite insignificant. | ||
| 311 | ;; | ||
| 312 | ;; Now, what about the filter alists? There are three of them, though | ||
| 313 | ;; only two sets of parameters: | ||
| 314 | ;; | ||
| 315 | ;; - `frameset-session-filter-alist' contains these filters that allow to | ||
| 316 | ;; save and restore framesets in-session, without the need to serialize | ||
| 317 | ;; the frameset or save it to disk (for example, to save a frameset in a | ||
| 318 | ;; register and restore it later). Filters in this list do not remove | ||
| 319 | ;; live objects, except in `minibuffer', which is dealt especially by | ||
| 320 | ;; `frameset-save' / `frameset-restore'. | ||
| 321 | ;; | ||
| 322 | ;; - `frameset-persistent-filter-alist' is the whole deal. It does all | ||
| 323 | ;; the filtering described above, and the result is ready to be saved on | ||
| 324 | ;; disk without loss of information. That's the format used by the | ||
| 325 | ;; desktop.el package, for example. | ||
| 326 | ;; | ||
| 327 | ;; IMPORTANT: These variables share structure and should never be modified. | ||
| 328 | ;; | ||
| 329 | ;; - `frameset-filter-alist': The value of this variable is the default | ||
| 330 | ;; value for the FILTERS arguments of `frameset-save' and | ||
| 331 | ;; `frameset-restore'. It is set to `frameset-persistent-filter-alist', | ||
| 332 | ;; though it can be changed by specific applications. | ||
| 333 | ;; | ||
| 334 | ;; How to use them? | ||
| 335 | ;; | ||
| 336 | ;; The simplest way is just do nothing. The default should work | ||
| 337 | ;; reasonably and sensibly enough. But, what if you really need a | ||
| 338 | ;; customized filter alist? Then you can create your own variable | ||
| 339 | ;; | ||
| 340 | ;; (defvar my-filter-alist | ||
| 341 | ;; '((my-param1 . :never) | ||
| 342 | ;; (my-param2 . :save) | ||
| 343 | ;; (my-param3 . :restore) | ||
| 344 | ;; (my-param4 . my-filtering-function-without-args) | ||
| 345 | ;; (my-param5 my-filtering-function-with arg1 arg2) | ||
| 346 | ;; ;;; many other parameters | ||
| 347 | ;; ) | ||
| 348 | ;; "My customized parameter filter alist.") | ||
| 349 | ;; | ||
| 350 | ;; or, if you're only changing a few items, | ||
| 351 | ;; | ||
| 352 | ;; (defvar my-filter-alist | ||
| 353 | ;; (nconc '((my-param1 . :never) | ||
| 354 | ;; (my-param2 . my-filtering-function)) | ||
| 355 | ;; frameset-filter-alist) | ||
| 356 | ;; "My brief customized parameter filter alist.") | ||
| 357 | ;; | ||
| 358 | ;; and pass it to the FILTER arg of the save/restore functions, | ||
| 359 | ;; ALWAYS taking care of not modifying the original lists; if you're | ||
| 360 | ;; going to do any modifying of my-filter-alist, please use | ||
| 361 | ;; | ||
| 362 | ;; (nconc '((my-param1 . :never) ...) | ||
| 363 | ;; (copy-sequence frameset-filter-alist)) | ||
| 364 | ;; | ||
| 365 | ;; One thing you shouldn't forget is that they are alists, so searching | ||
| 366 | ;; in them is sequential. If you just want to change the default of | ||
| 367 | ;; `name' to allow it to be saved, you can set (name . nil) in your | ||
| 368 | ;; customized filter alist; it will take precedence over the latter | ||
| 369 | ;; setting. In case you decide that you *always* want to save `name', | ||
| 370 | ;; you can add it to `frameset-filter-alist': | ||
| 371 | ;; | ||
| 372 | ;; (push '(name . nil) frameset-filter-alist) | ||
| 373 | ;; | ||
| 374 | ;; In certain applications, having a parameter filtering function like | ||
| 375 | ;; `frameset-filter-params' can be useful, even if you're not using | ||
| 376 | ;; framesets. The interface of `frameset-filter-params' is generic | ||
| 377 | ;; and does not depend of global state, with one exception: it uses | ||
| 378 | ;; the internal variable `frameset--target-display' to decide if, and | ||
| 379 | ;; how, to modify the `display' parameter of FILTERED. But that | ||
| 380 | ;; should not represent any problem, because it's only meaningful | ||
| 381 | ;; when restoring, and customized uses of `frameset-filter-params' | ||
| 382 | ;; are likely to use their own filter alist and just call | ||
| 383 | ;; | ||
| 384 | ;; (setq my-filtered (frameset-filter-params my-params my-filters t)) | ||
| 385 | ;; | ||
| 386 | ;; In case you want to use it with the standard filters, you can | ||
| 387 | ;; wrap the call to `frameset-filter-params' in a let form to bind | ||
| 388 | ;; `frameset--target-display' to nil or the desired value. | ||
| 389 | ;; | ||
| 390 | |||
| 134 | ;;;###autoload | 391 | ;;;###autoload |
| 135 | (defvar frameset-live-filter-alist | 392 | (defvar frameset-session-filter-alist |
| 136 | '((name . :never) | 393 | '((name . :never) |
| 137 | (left . frameset-filter-iconified) | 394 | (left . frameset-filter-iconified) |
| 138 | (minibuffer . frameset-filter-minibuffer) | 395 | (minibuffer . frameset-filter-minibuffer) |
| @@ -147,33 +404,35 @@ See `frameset-filter-alist' for a full description.") | |||
| 147 | (buffer-list . :never) | 404 | (buffer-list . :never) |
| 148 | (buffer-predicate . :never) | 405 | (buffer-predicate . :never) |
| 149 | (buried-buffer-list . :never) | 406 | (buried-buffer-list . :never) |
| 150 | (font . frameset-filter-save-param) | 407 | (font . frameset-filter-shelve-param) |
| 151 | (foreground-color . frameset-filter-sanitize-color) | 408 | (foreground-color . frameset-filter-sanitize-color) |
| 152 | (fullscreen . frameset-filter-save-param) | 409 | (fullscreen . frameset-filter-shelve-param) |
| 153 | (GUI:font . frameset-filter-restore-param) | 410 | (GUI:font . frameset-filter-unshelve-param) |
| 154 | (GUI:fullscreen . frameset-filter-restore-param) | 411 | (GUI:fullscreen . frameset-filter-unshelve-param) |
| 155 | (GUI:height . frameset-filter-restore-param) | 412 | (GUI:height . frameset-filter-unshelve-param) |
| 156 | (GUI:width . frameset-filter-restore-param) | 413 | (GUI:width . frameset-filter-unshelve-param) |
| 157 | (height . frameset-filter-save-param) | 414 | (height . frameset-filter-shelve-param) |
| 158 | (outer-window-id . :never) | 415 | (outer-window-id . :never) |
| 159 | (parent-id . :never) | 416 | (parent-id . :never) |
| 160 | (tty . frameset-filter-tty-to-GUI) | 417 | (tty . frameset-filter-tty-to-GUI) |
| 161 | (tty-type . frameset-filter-tty-to-GUI) | 418 | (tty-type . frameset-filter-tty-to-GUI) |
| 162 | (width . frameset-filter-save-param) | 419 | (width . frameset-filter-shelve-param) |
| 163 | (window-id . :never) | 420 | (window-id . :never) |
| 164 | (window-system . :never)) | 421 | (window-system . :never)) |
| 165 | frameset-live-filter-alist) | 422 | frameset-session-filter-alist) |
| 166 | "Recommended set of parameters to filter for persistent framesets. | 423 | "Parameters to filter for persistent framesets. |
| 167 | See `frameset-filter-alist' for a full description.") | 424 | See `frameset-filter-alist' for a full description.") |
| 168 | 425 | ||
| 169 | ;;;###autoload | 426 | ;;;###autoload |
| 170 | (defvar frameset-filter-alist frameset-persistent-filter-alist | 427 | (defvar frameset-filter-alist frameset-persistent-filter-alist |
| 171 | "Alist of frame parameters and filtering functions. | 428 | "Alist of frame parameters and filtering functions. |
| 172 | 429 | ||
| 173 | This alist is the default value of the :filters arguments of | 430 | This alist is the default value of the FILTERS argument of |
| 174 | `frameset-save' and `frameset-restore' (which see). On saving, | 431 | `frameset-save' and `frameset-restore' (which see). |
| 175 | PARAMETERS is the parameter alist of each frame processed, and | 432 | |
| 176 | FILTERED is the parameter alist that gets saved to the frameset. | 433 | On saving, PARAMETERS is the parameter alist of each frame processed, |
| 434 | and FILTERED is the parameter alist that gets saved to the frameset. | ||
| 435 | |||
| 177 | On restoring, PARAMETERS is the parameter alist extracted from the | 436 | On restoring, PARAMETERS is the parameter alist extracted from the |
| 178 | frameset, and FILTERED is the resulting frame parameter alist used | 437 | frameset, and FILTERED is the resulting frame parameter alist used |
| 179 | to restore the frame. | 438 | to restore the frame. |
| @@ -200,7 +459,7 @@ where | |||
| 200 | FILTERED The resulting alist (so far). | 459 | FILTERED The resulting alist (so far). |
| 201 | PARAMETERS The complete alist of parameters being filtered, | 460 | PARAMETERS The complete alist of parameters being filtered, |
| 202 | SAVING Non-nil if filtering before saving state, nil if filtering | 461 | SAVING Non-nil if filtering before saving state, nil if filtering |
| 203 | before restoring it. | 462 | before restoring it. |
| 204 | ARGS Any additional arguments specified in the ACTION. | 463 | ARGS Any additional arguments specified in the ACTION. |
| 205 | 464 | ||
| 206 | FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. | 465 | FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. |
| @@ -223,20 +482,20 @@ defined with ACTION = nil.") | |||
| 223 | 482 | ||
| 224 | (defun frameset-switch-to-gui-p (parameters) | 483 | (defun frameset-switch-to-gui-p (parameters) |
| 225 | "True when switching to a graphic display. | 484 | "True when switching to a graphic display. |
| 226 | Return t if PARAMETERS describes a text-only terminal and | 485 | Return non-nil if the parameter alist PARAMETERS describes a frame on a |
| 227 | the target is a graphic display; otherwise return nil. | 486 | text-only terminal, and the frame is being restored on a graphic display; |
| 228 | Only meaningful when called from a filtering function in | 487 | otherwise return nil. Only meaningful when called from a filtering |
| 229 | `frameset-filter-alist'." | 488 | function in `frameset-filter-alist'." |
| 230 | (and frameset--target-display ; we're switching | 489 | (and frameset--target-display ; we're switching |
| 231 | (null (cdr (assq 'display parameters))) ; from a tty | 490 | (null (cdr (assq 'display parameters))) ; from a tty |
| 232 | (cdr frameset--target-display))) ; to a GUI display | 491 | (cdr frameset--target-display))) ; to a GUI display |
| 233 | 492 | ||
| 234 | (defun frameset-switch-to-tty-p (parameters) | 493 | (defun frameset-switch-to-tty-p (parameters) |
| 235 | "True when switching to a text-only terminal. | 494 | "True when switching to a text-only terminal. |
| 236 | Return t if PARAMETERS describes a graphic display and | 495 | Return non-nil if the parameter alist PARAMETERS describes a frame on a |
| 237 | the target is a text-only terminal; otherwise return nil. | 496 | graphic display, and the frame is being restored on a text-only terminal; |
| 238 | Only meaningful when called from a filtering function in | 497 | otherwise return nil. Only meaningful when called from a filtering |
| 239 | `frameset-filter-alist'." | 498 | function in `frameset-filter-alist'." |
| 240 | (and frameset--target-display ; we're switching | 499 | (and frameset--target-display ; we're switching |
| 241 | (cdr (assq 'display parameters)) ; from a GUI display | 500 | (cdr (assq 'display parameters)) ; from a GUI display |
| 242 | (null (cdr frameset--target-display)))) ; to a tty | 501 | (null (cdr frameset--target-display)))) ; to a tty |
| @@ -245,7 +504,7 @@ Only meaningful when called from a filtering function in | |||
| 245 | "Remove CURRENT when switching from tty to a graphic display. | 504 | "Remove CURRENT when switching from tty to a graphic display. |
| 246 | 505 | ||
| 247 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 506 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 248 | see the docstring of `frameset-filter-alist'." | 507 | see `frameset-filter-alist'." |
| 249 | (or saving | 508 | (or saving |
| 250 | (not (frameset-switch-to-gui-p parameters)))) | 509 | (not (frameset-switch-to-gui-p parameters)))) |
| 251 | 510 | ||
| @@ -254,30 +513,30 @@ see the docstring of `frameset-filter-alist'." | |||
| 254 | Useful as a filter function for tty-specific parameters. | 513 | Useful as a filter function for tty-specific parameters. |
| 255 | 514 | ||
| 256 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 515 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 257 | see the docstring of `frameset-filter-alist'." | 516 | see `frameset-filter-alist'." |
| 258 | (or saving | 517 | (or saving |
| 259 | (not (frameset-switch-to-gui-p parameters)) | 518 | (not (frameset-switch-to-gui-p parameters)) |
| 260 | (not (stringp (cdr current))) | 519 | (not (stringp (cdr current))) |
| 261 | (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) | 520 | (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) |
| 262 | 521 | ||
| 263 | (defun frameset-filter-minibuffer (current _filtered _parameters saving) | 522 | (defun frameset-filter-minibuffer (current _filtered _parameters saving) |
| 264 | "When saving, convert (minibuffer . #<window>) parameter to (minibuffer . t). | 523 | "When saving, convert (minibuffer . #<window>) to (minibuffer . t). |
| 265 | 524 | ||
| 266 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 525 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 267 | see the docstring of `frameset-filter-alist'." | 526 | see `frameset-filter-alist'." |
| 268 | (or (not saving) | 527 | (or (not saving) |
| 269 | (if (windowp (cdr current)) | 528 | (if (windowp (cdr current)) |
| 270 | '(minibuffer . t) | 529 | '(minibuffer . t) |
| 271 | t))) | 530 | t))) |
| 272 | 531 | ||
| 273 | (defun frameset-filter-save-param (current _filtered parameters saving | 532 | (defun frameset-filter-shelve-param (current _filtered parameters saving |
| 274 | &optional prefix) | 533 | &optional prefix) |
| 275 | "When switching to a tty frame, save parameter P as PREFIX:P. | 534 | "When switching to a tty frame, save parameter P as PREFIX:P. |
| 276 | The parameter can be later restored with `frameset-filter-restore-param'. | 535 | The parameter can be later restored with `frameset-filter-unshelve-param'. |
| 277 | PREFIX defaults to `GUI'. | 536 | PREFIX defaults to `GUI'. |
| 278 | 537 | ||
| 279 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 538 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 280 | see the docstring of `frameset-filter-alist'." | 539 | see `frameset-filter-alist'." |
| 281 | (unless prefix (setq prefix 'GUI)) | 540 | (unless prefix (setq prefix 'GUI)) |
| 282 | (cond (saving t) | 541 | (cond (saving t) |
| 283 | ((frameset-switch-to-tty-p parameters) | 542 | ((frameset-switch-to-tty-p parameters) |
| @@ -289,12 +548,12 @@ see the docstring of `frameset-filter-alist'." | |||
| 289 | (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) | 548 | (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) |
| 290 | (t t))) | 549 | (t t))) |
| 291 | 550 | ||
| 292 | (defun frameset-filter-restore-param (current filtered parameters saving) | 551 | (defun frameset-filter-unshelve-param (current filtered parameters saving) |
| 293 | "When switching to a GUI frame, restore PREFIX:P parameter as P. | 552 | "When switching to a GUI frame, restore PREFIX:P parameter as P. |
| 294 | CURRENT must be of the form (PREFIX:P . value). | 553 | CURRENT must be of the form (PREFIX:P . value). |
| 295 | 554 | ||
| 296 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 555 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 297 | see the docstring of `frameset-filter-alist'." | 556 | see `frameset-filter-alist'." |
| 298 | (or saving | 557 | (or saving |
| 299 | (not (frameset-switch-to-gui-p parameters)) | 558 | (not (frameset-switch-to-gui-p parameters)) |
| 300 | (let* ((prefix:p (symbol-name (car current))) | 559 | (let* ((prefix:p (symbol-name (car current))) |
| @@ -314,7 +573,7 @@ meaningless in an iconified frame, so the frame is restored in a | |||
| 314 | default position. | 573 | default position. |
| 315 | 574 | ||
| 316 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, | 575 | For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, |
| 317 | see the docstring of `frameset-filter-alist'." | 576 | see `frameset-filter-alist'." |
| 318 | (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) | 577 | (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) |
| 319 | 578 | ||
| 320 | (defun frameset-filter-params (parameters filter-alist saving) | 579 | (defun frameset-filter-params (parameters filter-alist saving) |
| @@ -382,7 +641,7 @@ newest frame keeps the id and the old frame's is set to nil." | |||
| 382 | (string= (frameset-frame-id frame) id)) | 641 | (string= (frameset-frame-id frame) id)) |
| 383 | 642 | ||
| 384 | ;;;###autoload | 643 | ;;;###autoload |
| 385 | (defun frameset-locate-frame-id (id &optional frame-list) | 644 | (defun frameset-frame-with-id (id &optional frame-list) |
| 386 | "Return the live frame with id ID, if exists; else nil. | 645 | "Return the live frame with id ID, if exists; else nil. |
| 387 | If FRAME-LIST is a list of frames, check these frames only. | 646 | If FRAME-LIST is a list of frames, check these frames only. |
| 388 | If nil, check all live frames." | 647 | If nil, check all live frames." |
| @@ -394,7 +653,7 @@ If nil, check all live frames." | |||
| 394 | 653 | ||
| 395 | ;; Saving framesets | 654 | ;; Saving framesets |
| 396 | 655 | ||
| 397 | (defun frameset--process-minibuffer-frames (frame-list) | 656 | (defun frameset--record-minibuffer-relationships (frame-list) |
| 398 | "Process FRAME-LIST and record minibuffer relationships. | 657 | "Process FRAME-LIST and record minibuffer relationships. |
| 399 | FRAME-LIST is a list of frames. Internal use only." | 658 | FRAME-LIST is a list of frames. Internal use only." |
| 400 | ;; Record frames with their own minibuffer | 659 | ;; Record frames with their own minibuffer |
| @@ -423,11 +682,16 @@ FRAME-LIST is a list of frames. Internal use only." | |||
| 423 | (cons nil id))))))) | 682 | (cons nil id))))))) |
| 424 | 683 | ||
| 425 | ;;;###autoload | 684 | ;;;###autoload |
| 426 | (cl-defun frameset-save (frame-list &key filters predicate properties) | 685 | (cl-defun frameset-save (frame-list |
| 427 | "Return the frameset of FRAME-LIST, a list of frames. | 686 | &key app name description |
| 687 | filters predicate properties) | ||
| 688 | "Return a frameset for FRAME-LIST, a list of frames. | ||
| 428 | Dead frames and non-frame objects are silently removed from the list. | 689 | Dead frames and non-frame objects are silently removed from the list. |
| 429 | If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). | 690 | If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). |
| 430 | FILTERS is an alist of parameter filters, or `frameset-filter-alist' if nil. | 691 | APP, NAME and DESCRIPTION are optional data; see the docstring of the |
| 692 | `frameset' defstruct for details. | ||
| 693 | FILTERS is an alist of parameter filters; if nil, the value of the variable | ||
| 694 | `frameset-filter-alist' is used instead. | ||
| 431 | PREDICATE is a predicate function, which must return non-nil for frames that | 695 | PREDICATE is a predicate function, which must return non-nil for frames that |
| 432 | should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved. | 696 | should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved. |
| 433 | PROPERTIES is a user-defined property list to add to the frameset." | 697 | PROPERTIES is a user-defined property list to add to the frameset." |
| @@ -436,16 +700,20 @@ PROPERTIES is a user-defined property list to add to the frameset." | |||
| 436 | (if predicate | 700 | (if predicate |
| 437 | (cl-delete-if-not predicate list) | 701 | (cl-delete-if-not predicate list) |
| 438 | list)))) | 702 | list)))) |
| 439 | (frameset--process-minibuffer-frames frames) | 703 | (frameset--record-minibuffer-relationships frames) |
| 440 | (make-frameset properties | 704 | (make-frameset :app app |
| 441 | (mapcar | 705 | :name name |
| 442 | (lambda (frame) | 706 | :description description |
| 443 | (cons | 707 | :properties properties |
| 444 | (frameset-filter-params (frame-parameters frame) | 708 | :states (mapcar |
| 445 | (or filters frameset-filter-alist) | 709 | (lambda (frame) |
| 446 | t) | 710 | (cons |
| 447 | (window-state-get (frame-root-window frame) t))) | 711 | (frameset-filter-params (frame-parameters frame) |
| 448 | frames)))) | 712 | (or filters |
| 713 | frameset-filter-alist) | ||
| 714 | t) | ||
| 715 | (window-state-get (frame-root-window frame) t))) | ||
| 716 | frames)))) | ||
| 449 | 717 | ||
| 450 | 718 | ||
| 451 | ;; Restoring framesets | 719 | ;; Restoring framesets |
| @@ -534,7 +802,7 @@ NOTE: This only works for non-iconified frames." | |||
| 534 | (when params | 802 | (when params |
| 535 | (modify-frame-parameters frame params)))))) | 803 | (modify-frame-parameters frame params)))))) |
| 536 | 804 | ||
| 537 | (defun frameset--find-frame (predicate display &rest args) | 805 | (defun frameset--find-frame-if (predicate display &rest args) |
| 538 | "Find a frame in `frameset--reuse-list' satisfying PREDICATE. | 806 | "Find a frame in `frameset--reuse-list' satisfying PREDICATE. |
| 539 | Look through available frames whose display property matches DISPLAY | 807 | Look through available frames whose display property matches DISPLAY |
| 540 | and return the first one for which (PREDICATE frame ARGS) returns t. | 808 | and return the first one for which (PREDICATE frame ARGS) returns t. |
| @@ -545,9 +813,9 @@ If PREDICATE is nil, it is always satisfied. Internal use only." | |||
| 545 | (apply predicate frame args)))) | 813 | (apply predicate frame args)))) |
| 546 | frameset--reuse-list)) | 814 | frameset--reuse-list)) |
| 547 | 815 | ||
| 548 | (defun frameset--reuse-frame (display frame-cfg) | 816 | (defun frameset--reuse-frame (display parameters) |
| 549 | "Look for an existing frame to reuse. | 817 | "Return an existing frame to reuse, or nil if none found. |
| 550 | DISPLAY is the display where the frame will be shown, and FRAME-CFG | 818 | DISPLAY is the display where the frame will be shown, and PARAMETERS |
| 551 | is the parameter alist of the frame being restored. Internal use only." | 819 | is the parameter alist of the frame being restored. Internal use only." |
| 552 | (let ((frame nil) | 820 | (let ((frame nil) |
| 553 | mini) | 821 | mini) |
| @@ -561,19 +829,19 @@ is the parameter alist of the frame being restored. Internal use only." | |||
| 561 | ;; will usually have only one frame, and should already work. | 829 | ;; will usually have only one frame, and should already work. |
| 562 | (cond ((null display) | 830 | (cond ((null display) |
| 563 | ;; When the target is tty, every existing frame is reusable. | 831 | ;; When the target is tty, every existing frame is reusable. |
| 564 | (setq frame (frameset--find-frame nil display))) | 832 | (setq frame (frameset--find-frame-if nil display))) |
| 565 | ((car (setq mini (cdr (assq 'frameset--mini frame-cfg)))) | 833 | ((car (setq mini (cdr (assq 'frameset--mini parameters)))) |
| 566 | ;; If the frame has its own minibuffer, let's see whether | 834 | ;; If the frame has its own minibuffer, let's see whether |
| 567 | ;; that frame has already been loaded (which can happen after | 835 | ;; that frame has already been loaded (which can happen after |
| 568 | ;; M-x desktop-read). | 836 | ;; M-x desktop-read). |
| 569 | (setq frame (frameset--find-frame | 837 | (setq frame (frameset--find-frame-if |
| 570 | (lambda (f id) | 838 | (lambda (f id) |
| 571 | (frameset-frame-id-equal-p f id)) | 839 | (frameset-frame-id-equal-p f id)) |
| 572 | display (cdr (assq 'frameset--id frame-cfg)))) | 840 | display (cdr (assq 'frameset--id parameters)))) |
| 573 | ;; If it has not been loaded, and it is not a minibuffer-only frame, | 841 | ;; If it has not been loaded, and it is not a minibuffer-only frame, |
| 574 | ;; let's look for an existing non-minibuffer-only frame to reuse. | 842 | ;; let's look for an existing non-minibuffer-only frame to reuse. |
| 575 | (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only)) | 843 | (unless (or frame (eq (cdr (assq 'minibuffer parameters)) 'only)) |
| 576 | (setq frame (frameset--find-frame | 844 | (setq frame (frameset--find-frame-if |
| 577 | (lambda (f) | 845 | (lambda (f) |
| 578 | (let ((w (frame-parameter f 'minibuffer))) | 846 | (let ((w (frame-parameter f 'minibuffer))) |
| 579 | (and (window-live-p w) | 847 | (and (window-live-p w) |
| @@ -583,39 +851,38 @@ is the parameter alist of the frame being restored. Internal use only." | |||
| 583 | (mini | 851 | (mini |
| 584 | ;; For minibufferless frames, check whether they already exist, | 852 | ;; For minibufferless frames, check whether they already exist, |
| 585 | ;; and that they are linked to the right minibuffer frame. | 853 | ;; and that they are linked to the right minibuffer frame. |
| 586 | (setq frame (frameset--find-frame | 854 | (setq frame (frameset--find-frame-if |
| 587 | (lambda (f id mini-id) | 855 | (lambda (f id mini-id) |
| 588 | (and (frameset-frame-id-equal-p f id) | 856 | (and (frameset-frame-id-equal-p f id) |
| 589 | (frameset-frame-id-equal-p (window-frame | 857 | (frameset-frame-id-equal-p (window-frame |
| 590 | (minibuffer-window f)) | 858 | (minibuffer-window f)) |
| 591 | mini-id))) | 859 | mini-id))) |
| 592 | display (cdr (assq 'frameset--id frame-cfg)) (cdr mini)))) | 860 | display (cdr (assq 'frameset--id parameters)) (cdr mini)))) |
| 593 | (t | 861 | (t |
| 594 | ;; Default to just finding a frame in the same display. | 862 | ;; Default to just finding a frame in the same display. |
| 595 | (setq frame (frameset--find-frame nil display)))) | 863 | (setq frame (frameset--find-frame-if nil display)))) |
| 596 | ;; If found, remove from the list. | 864 | ;; If found, remove from the list. |
| 597 | (when frame | 865 | (when frame |
| 598 | (setq frameset--reuse-list (delq frame frameset--reuse-list))) | 866 | (setq frameset--reuse-list (delq frame frameset--reuse-list))) |
| 599 | frame)) | 867 | frame)) |
| 600 | 868 | ||
| 601 | (defun frameset--initial-params (frame-cfg) | 869 | (defun frameset--initial-params (parameters) |
| 602 | "Return parameters from FRAME-CFG that should not be changed later. | 870 | "Return a list of PARAMETERS that must be set when creating the frame. |
| 603 | Setting position and size parameters as soon as possible helps reducing | 871 | Setting position and size parameters as soon as possible helps reducing |
| 604 | flickering; other parameters, like `minibuffer' and `border-width', must | 872 | flickering; other parameters, like `minibuffer' and `border-width', can |
| 605 | be set when creating the frame because they can not be changed later. | 873 | not be changed once the frame has been created. Internal use only." |
| 606 | Internal use only." | ||
| 607 | (cl-loop for param in '(left top with height border-width minibuffer) | 874 | (cl-loop for param in '(left top with height border-width minibuffer) |
| 608 | collect (assq param frame-cfg))) | 875 | collect (assq param parameters))) |
| 609 | 876 | ||
| 610 | (defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) | 877 | (defun frameset--restore-frame (parameters window-state filters force-onscreen) |
| 611 | "Set up and return a frame according to its saved state. | 878 | "Set up and return a frame according to its saved state. |
| 612 | That means either reusing an existing frame or creating one anew. | 879 | That means either reusing an existing frame or creating one anew. |
| 613 | FRAME-CFG is the frame's parameter alist; WINDOW-CFG is its window state. | 880 | PARAMETERS is the frame's parameter alist; WINDOW-STATE is its window state. |
| 614 | For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. | 881 | For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. |
| 615 | Internal use only." | 882 | Internal use only." |
| 616 | (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) | 883 | (let* ((fullscreen (cdr (assq 'fullscreen parameters))) |
| 617 | (lines (assq 'tool-bar-lines frame-cfg)) | 884 | (lines (assq 'tool-bar-lines parameters)) |
| 618 | (filtered-cfg (frameset-filter-params frame-cfg filters nil)) | 885 | (filtered-cfg (frameset-filter-params parameters filters nil)) |
| 619 | (display (cdr (assq 'display filtered-cfg))) ;; post-filtering | 886 | (display (cdr (assq 'display filtered-cfg))) ;; post-filtering |
| 620 | alt-cfg frame) | 887 | alt-cfg frame) |
| 621 | 888 | ||
| @@ -673,7 +940,7 @@ Internal use only." | |||
| 673 | (when lines (push lines alt-cfg)) | 940 | (when lines (push lines alt-cfg)) |
| 674 | (when alt-cfg (modify-frame-parameters frame alt-cfg)) | 941 | (when alt-cfg (modify-frame-parameters frame alt-cfg)) |
| 675 | ;; Now restore window state. | 942 | ;; Now restore window state. |
| 676 | (window-state-put window-cfg (frame-root-window frame) 'safe) | 943 | (window-state-put window-state (frame-root-window frame) 'safe) |
| 677 | frame)) | 944 | frame)) |
| 678 | 945 | ||
| 679 | (defun frameset--minibufferless-last-p (state1 state2) | 946 | (defun frameset--minibufferless-last-p (state1 state2) |
| @@ -689,7 +956,8 @@ Internal use only." | |||
| 689 | (t t)))) | 956 | (t t)))) |
| 690 | 957 | ||
| 691 | (defun frameset-keep-original-display-p (force-display) | 958 | (defun frameset-keep-original-display-p (force-display) |
| 692 | "True if saved frames' displays should be honored." | 959 | "True if saved frames' displays should be honored. |
| 960 | For the meaning of FORCE-DISPLAY, see `frameset-restore'." | ||
| 693 | (cond ((daemonp) t) | 961 | (cond ((daemonp) t) |
| 694 | ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display? | 962 | ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display? |
| 695 | (t (not force-display)))) | 963 | (t (not force-display)))) |
| @@ -700,26 +968,35 @@ Internal use only." | |||
| 700 | 968 | ||
| 701 | ;;;###autoload | 969 | ;;;###autoload |
| 702 | (cl-defun frameset-restore (frameset | 970 | (cl-defun frameset-restore (frameset |
| 703 | &key filters reuse-frames force-display force-onscreen) | 971 | &key predicate filters reuse-frames |
| 972 | force-display force-onscreen) | ||
| 704 | "Restore a FRAMESET into the current display(s). | 973 | "Restore a FRAMESET into the current display(s). |
| 705 | 974 | ||
| 706 | FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. | 975 | PREDICATE is a function called with two arguments, the parameter alist |
| 976 | and the window-state of the frame being restored, in that order (see | ||
| 977 | the docstring of the `frameset' defstruct for additional details). | ||
| 978 | If PREDICATE returns nil, the frame described by that parameter alist | ||
| 979 | and window-state is not restored. | ||
| 980 | |||
| 981 | FILTERS is an alist of parameter filters; if nil, the value of | ||
| 982 | `frameset-filter-alist' is used instead. | ||
| 707 | 983 | ||
| 708 | REUSE-FRAMES selects the policy to use to reuse frames when restoring: | 984 | REUSE-FRAMES selects the policy to use to reuse frames when restoring: |
| 709 | t Reuse any existing frame if possible; delete leftover frames. | 985 | t Reuse existing frames if possible, and delete those not reused. |
| 710 | nil Restore frameset in new frames and delete existing frames. | 986 | nil Restore frameset in new frames and delete existing frames. |
| 711 | :keep Restore frameset in new frames and keep the existing ones. | 987 | :keep Restore frameset in new frames and keep the existing ones. |
| 712 | LIST A list of frames to reuse; only these are reused (if possible), | 988 | LIST A list of frames to reuse; only these are reused (if possible). |
| 713 | and any leftover ones are deleted; other frames not on this | 989 | Remaining frames in this list are deleted; other frames not |
| 714 | list are left untouched. | 990 | included on the list are left untouched. |
| 715 | 991 | ||
| 716 | FORCE-DISPLAY can be: | 992 | FORCE-DISPLAY can be: |
| 717 | t Frames are restored in the current display. | 993 | t Frames are restored in the current display. |
| 718 | nil Frames are restored, if possible, in their original displays. | 994 | nil Frames are restored, if possible, in their original displays. |
| 719 | :delete Frames in other displays are deleted instead of restored. | 995 | :delete Frames in other displays are deleted instead of restored. |
| 720 | PRED A function called with one argument, the parameter alist; | 996 | PRED A function called with two arguments, the parameter alist and |
| 721 | it must return t, nil or `:delete', as above but affecting | 997 | the window state (in that order). It must return t, nil or |
| 722 | only the frame that will be created from that parameter alist. | 998 | `:delete', as above but affecting only the frame that will |
| 999 | be created from that parameter alist. | ||
| 723 | 1000 | ||
| 724 | FORCE-ONSCREEN can be: | 1001 | FORCE-ONSCREEN can be: |
| 725 | t Force onscreen only those frames that are fully offscreen. | 1002 | t Force onscreen only those frames that are fully offscreen. |
| @@ -736,7 +1013,7 @@ affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being | |||
| 736 | restored before that happens, and FORCE-ONSCREEN affects the frame once | 1013 | restored before that happens, and FORCE-ONSCREEN affects the frame once |
| 737 | it has been restored. | 1014 | it has been restored. |
| 738 | 1015 | ||
| 739 | All keywords default to nil." | 1016 | All keyword parameters default to nil." |
| 740 | 1017 | ||
| 741 | (cl-assert (frameset-p frameset)) | 1018 | (cl-assert (frameset-p frameset)) |
| 742 | 1019 | ||
| @@ -751,8 +1028,8 @@ All keywords default to nil." | |||
| 751 | ((pred consp) | 1028 | ((pred consp) |
| 752 | (setq frameset--reuse-list (copy-sequence reuse-frames) | 1029 | (setq frameset--reuse-list (copy-sequence reuse-frames) |
| 753 | other-frames (cl-delete-if (lambda (frame) | 1030 | other-frames (cl-delete-if (lambda (frame) |
| 754 | (memq frame frameset--reuse-list)) | 1031 | (memq frame frameset--reuse-list)) |
| 755 | (frame-list)))) | 1032 | (frame-list)))) |
| 756 | (_ | 1033 | (_ |
| 757 | (setq frameset--reuse-list (frame-list) | 1034 | (setq frameset--reuse-list (frame-list) |
| 758 | other-frames nil))) | 1035 | other-frames nil))) |
| @@ -761,73 +1038,74 @@ All keywords default to nil." | |||
| 761 | ;; after the frames that contain their minibuffer windows. | 1038 | ;; after the frames that contain their minibuffer windows. |
| 762 | (dolist (state (sort (copy-sequence (frameset-states frameset)) | 1039 | (dolist (state (sort (copy-sequence (frameset-states frameset)) |
| 763 | #'frameset--minibufferless-last-p)) | 1040 | #'frameset--minibufferless-last-p)) |
| 764 | (condition-case-unless-debug err | 1041 | (pcase-let ((`(,frame-cfg . ,window-cfg) state)) |
| 765 | (pcase-let* ((`(,frame-cfg . ,window-cfg) state) | 1042 | (when (or (null predicate) (funcall predicate frame-cfg window-cfg)) |
| 766 | ((and d-mini `(,hasmini . ,mb-id)) | 1043 | (condition-case-unless-debug err |
| 767 | (cdr (assq 'frameset--mini frame-cfg))) | 1044 | (let* ((d-mini (cdr (assq 'frameset--mini frame-cfg))) |
| 768 | (default (and (booleanp mb-id) mb-id)) | 1045 | (mb-id (cdr d-mini)) |
| 769 | (force-display (if (functionp force-display) | 1046 | (default (and (booleanp mb-id) mb-id)) |
| 770 | (funcall force-display frame-cfg) | 1047 | (force-display (if (functionp force-display) |
| 771 | force-display)) | 1048 | (funcall force-display frame-cfg window-cfg) |
| 772 | (frame nil) (to-tty nil)) | 1049 | force-display)) |
| 773 | ;; Only set target if forcing displays and the target display is different. | 1050 | frame to-tty) |
| 774 | (cond ((frameset-keep-original-display-p force-display) | 1051 | ;; Only set target if forcing displays and the target display is different. |
| 775 | (setq frameset--target-display nil)) | 1052 | (cond ((frameset-keep-original-display-p force-display) |
| 776 | ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) | 1053 | (setq frameset--target-display nil)) |
| 777 | (setq frameset--target-display nil)) | 1054 | ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) |
| 778 | (t | 1055 | (setq frameset--target-display nil)) |
| 779 | (setq frameset--target-display (cons 'display | 1056 | (t |
| 780 | (frame-parameter nil 'display)) | 1057 | (setq frameset--target-display (cons 'display |
| 781 | to-tty (null (cdr frameset--target-display))))) | 1058 | (frame-parameter nil 'display)) |
| 782 | ;; Time to restore frames and set up their minibuffers as they were. | 1059 | to-tty (null (cdr frameset--target-display))))) |
| 783 | ;; We only skip a frame (thus deleting it) if either: | 1060 | ;; Time to restore frames and set up their minibuffers as they were. |
| 784 | ;; - we're switching displays, and the user chose the option to delete, or | 1061 | ;; We only skip a frame (thus deleting it) if either: |
| 785 | ;; - we're switching to tty, and the frame to restore is minibuffer-only. | 1062 | ;; - we're switching displays, and the user chose the option to delete, or |
| 786 | (unless (and frameset--target-display | 1063 | ;; - we're switching to tty, and the frame to restore is minibuffer-only. |
| 787 | (or (eq force-display :delete) | 1064 | (unless (and frameset--target-display |
| 788 | (and to-tty | 1065 | (or (eq force-display :delete) |
| 789 | (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) | 1066 | (and to-tty |
| 790 | ;; If keeping non-reusable frames, and the frameset--id of one of them | 1067 | (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) |
| 791 | ;; matches the id of a frame being restored (because, for example, the | 1068 | ;; If keeping non-reusable frames, and the frameset--id of one of them |
| 792 | ;; frameset has already been read in the same session), remove the | 1069 | ;; matches the id of a frame being restored (because, for example, the |
| 793 | ;; frameset--id from the non-reusable frame, which is not useful anymore. | 1070 | ;; frameset has already been read in the same session), remove the |
| 794 | (when (and other-frames | 1071 | ;; frameset--id from the non-reusable frame, which is not useful anymore. |
| 795 | (or (eq reuse-frames :keep) (consp reuse-frames))) | 1072 | (when (and other-frames |
| 796 | (let ((dup (frameset-locate-frame-id (cdr (assq 'frameset--id frame-cfg)) | 1073 | (or (eq reuse-frames :keep) (consp reuse-frames))) |
| 797 | other-frames))) | 1074 | (let ((dup (frameset-frame-with-id (cdr (assq 'frameset--id frame-cfg)) |
| 798 | (when dup | 1075 | other-frames))) |
| 799 | (set-frame-parameter dup 'frameset--id nil)))) | 1076 | (when dup |
| 800 | ;; Restore minibuffers. Some of this stuff could be done in a filter | 1077 | (set-frame-parameter dup 'frameset--id nil)))) |
| 801 | ;; function, but it would be messy because restoring minibuffers affects | 1078 | ;; Restore minibuffers. Some of this stuff could be done in a filter |
| 802 | ;; global state; it's best to do it here than add a bunch of global | 1079 | ;; function, but it would be messy because restoring minibuffers affects |
| 803 | ;; variables to pass info back-and-forth to/from the filter function. | 1080 | ;; global state; it's best to do it here than add a bunch of global |
| 804 | (cond | 1081 | ;; variables to pass info back-and-forth to/from the filter function. |
| 805 | ((null d-mini)) ;; No frameset--mini. Process as normal frame. | 1082 | (cond |
| 806 | (to-tty) ;; Ignore minibuffer stuff and process as normal frame. | 1083 | ((null d-mini)) ;; No frameset--mini. Process as normal frame. |
| 807 | (hasmini ;; Frame has minibuffer (or it is minibuffer-only). | 1084 | (to-tty) ;; Ignore minibuffer stuff and process as normal frame. |
| 808 | (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) | 1085 | ((car d-mini) ;; Frame has minibuffer (or it is minibuffer-only). |
| 809 | (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) | 1086 | (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) |
| 810 | frame-cfg)))) | 1087 | (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) |
| 811 | (t ;; Frame depends on other frame's minibuffer window. | 1088 | frame-cfg)))) |
| 812 | (let* ((mb-frame (or (frameset-locate-frame-id mb-id) | 1089 | (t ;; Frame depends on other frame's minibuffer window. |
| 813 | (error "Minibuffer frame %S not found" mb-id))) | 1090 | (let* ((mb-frame (or (frameset-frame-with-id mb-id) |
| 814 | (mb-param (assq 'minibuffer frame-cfg)) | 1091 | (error "Minibuffer frame %S not found" mb-id))) |
| 815 | (mb-window (minibuffer-window mb-frame))) | 1092 | (mb-param (assq 'minibuffer frame-cfg)) |
| 816 | (unless (and (window-live-p mb-window) | 1093 | (mb-window (minibuffer-window mb-frame))) |
| 817 | (window-minibuffer-p mb-window)) | 1094 | (unless (and (window-live-p mb-window) |
| 818 | (error "Not a minibuffer window %s" mb-window)) | 1095 | (window-minibuffer-p mb-window)) |
| 819 | (if mb-param | 1096 | (error "Not a minibuffer window %s" mb-window)) |
| 820 | (setcdr mb-param mb-window) | 1097 | (if mb-param |
| 821 | (push (cons 'minibuffer mb-window) frame-cfg))))) | 1098 | (setcdr mb-param mb-window) |
| 822 | ;; OK, we're ready at last to create (or reuse) a frame and | 1099 | (push (cons 'minibuffer mb-window) frame-cfg))))) |
| 823 | ;; restore the window config. | 1100 | ;; OK, we're ready at last to create (or reuse) a frame and |
| 824 | (setq frame (frameset--restore-frame frame-cfg window-cfg | 1101 | ;; restore the window config. |
| 825 | (or filters frameset-filter-alist) | 1102 | (setq frame (frameset--restore-frame frame-cfg window-cfg |
| 826 | force-onscreen)) | 1103 | (or filters frameset-filter-alist) |
| 827 | ;; Set default-minibuffer if required. | 1104 | force-onscreen)) |
| 828 | (when default (setq default-minibuffer-frame frame)))) | 1105 | ;; Set default-minibuffer if required. |
| 829 | (error | 1106 | (when default (setq default-minibuffer-frame frame)))) |
| 830 | (delay-warning 'frameset (error-message-string err) :error)))) | 1107 | (error |
| 1108 | (delay-warning 'frameset (error-message-string err) :error)))))) | ||
| 831 | 1109 | ||
| 832 | ;; In case we try to delete the initial frame, we want to make sure that | 1110 | ;; In case we try to delete the initial frame, we want to make sure that |
| 833 | ;; other frames are already visible (discussed in thread for bug#14841). | 1111 | ;; other frames are already visible (discussed in thread for bug#14841). |
| @@ -845,7 +1123,8 @@ All keywords default to nil." | |||
| 845 | (delete-frame frame) | 1123 | (delete-frame frame) |
| 846 | (error | 1124 | (error |
| 847 | (delay-warning 'frameset (error-message-string err)))))) | 1125 | (delay-warning 'frameset (error-message-string err)))))) |
| 848 | (setq frameset--reuse-list nil) | 1126 | (setq frameset--reuse-list nil |
| 1127 | frameset--target-display nil) | ||
| 849 | 1128 | ||
| 850 | ;; Make sure there's at least one visible frame. | 1129 | ;; Make sure there's at least one visible frame. |
| 851 | (unless (or (daemonp) (visible-frame-list)) | 1130 | (unless (or (daemonp) (visible-frame-list)) |