* bug#14964: 24.3.50; doc of `compare-window-configurations' @ 2013-07-27 3:14 Drew Adams 2013-07-27 8:18 ` martin rudalics 0 siblings, 1 reply; 21+ messages in thread From: Drew Adams @ 2013-07-27 3:14 UTC (permalink / raw) To: 14964 The doc doesn't tell you enough about what this function does to be able to use it. Compare how? What does a non-nil or nil return value mean? Does the order of the two arguments matter? What's going on here? What for? In GNU Emacs 24.3.50.1 (i686-pc-mingw32) of 2013-07-21 on ODIEONE Bzr revision: 113485 lekktu@gmail.com-20130722012547-e3b7qxn1dba5vf20 Windowing system distributor `Microsoft Corp.', version 6.1.7601 Configured using: `configure --prefix=/c/Devel/emacs/binary --enable-checking=yes,glyphs CFLAGS=-O0 -g3 LDFLAGS=-Lc:/Devel/emacs/lib CPPFLAGS=-Ic:/Devel/emacs/include' ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-27 3:14 bug#14964: 24.3.50; doc of `compare-window-configurations' Drew Adams @ 2013-07-27 8:18 ` martin rudalics 2013-07-27 19:39 ` Drew Adams 2022-04-21 13:42 ` Lars Ingebrigtsen 0 siblings, 2 replies; 21+ messages in thread From: martin rudalics @ 2013-07-27 8:18 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 > The doc doesn't tell you enough about what this function does to be able > to use it. Compare how? What does a non-nil or nil return value mean? > Does the order of the two arguments matter? What's going on here? What > for? I never understood the purpose of this function. Does anyone use it? martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-27 8:18 ` martin rudalics @ 2013-07-27 19:39 ` Drew Adams 2013-07-28 8:40 ` martin rudalics 2022-04-21 13:42 ` Lars Ingebrigtsen 1 sibling, 1 reply; 21+ messages in thread From: Drew Adams @ 2013-07-27 19:39 UTC (permalink / raw) To: martin rudalics; +Cc: 14964 > > The doc doesn't tell you enough about what this function does to be able > > to use it. Compare how? What does a non-nil or nil return value mean? > > Does the order of the two arguments matter? What's going on here? What > > for? > > I never understood the purpose of this function. Does anyone use it? 1. Dunno. Not I, at least not until I understand what it does etc. ;-) How anyone could introduce a function like this without offering a clue to what it is about is beyond me. Looking at window.c, from Emacs 24.3, at least, I see that a comment in the code says that this function returns t if the two window configs represent "the same state of affairs", and nil otherwise. It also says that the function is used by Fequal. But actually it seems it is used by internal_equal, which is used by several equality predicates, not just `equal': `eql', `equal-including-properties', `memql'. So based on that info I do not understand why this was ever added as a Lisp function. Perhaps someone thought we might do more with it in the future? Or perhaps it was thought that this would be faster than calling `equal' etc., which have to test a few things before then get to invoking this. Whatever the rationale, this function has been around for a long time. 2. Thank you, BTW, for adding Lisp-level things like `window-state-(get|put)'. 3. I would also like to see functions that accept or produce window and frame configurations optionally accept and produce also Lisp-readable equivalents. IOW, today, such configurations always use actual window and frame objects, which are not Lisp-readable. I would like to see them optionally (e.g. via optional arguments) use Lisp-readable frame and window states. IOW, make it simple to persist such configurations. ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-27 19:39 ` Drew Adams @ 2013-07-28 8:40 ` martin rudalics 2013-07-28 14:49 ` Drew Adams 0 siblings, 1 reply; 21+ messages in thread From: martin rudalics @ 2013-07-28 8:40 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 > So based on that info I do not understand why this was ever added as a Lisp > function. Perhaps someone thought we might do more with it in the future? > Or perhaps it was thought that this would be faster than calling `equal' etc., > which have to test a few things before then get to invoking this. > > Whatever the rationale, this function has been around for a long time. Maybe the idea was to not create anew a configuration that was already saved. > 3. I would also like to see functions that accept or produce window and frame > configurations optionally accept and produce also Lisp-readable equivalents. > > IOW, today, such configurations always use actual window and frame objects, > which are not Lisp-readable. I would like to see them optionally (e.g. via > optional arguments) use Lisp-readable frame and window states. IOW, make > it simple to persist such configurations. With window states I tried to approximate window configurations as close as possible. I don't know enough about frames to do the same for them. I bet that currently Juanma knows best whether this can be done in some reasonable way. martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 8:40 ` martin rudalics @ 2013-07-28 14:49 ` Drew Adams 2013-07-28 16:57 ` Juanma Barranquero 2013-07-29 7:54 ` martin rudalics 0 siblings, 2 replies; 21+ messages in thread From: Drew Adams @ 2013-07-28 14:49 UTC (permalink / raw) To: martin rudalics; +Cc: Juanma Barranquero, 14964 > > 3. I would also like to see functions that accept or produce window and > > frame configurations optionally accept and produce also Lisp-readable > > equivalents. > > > > IOW, today, such configurations always use actual window and frame > > objects, which are not Lisp-readable. I would like to see them optionally > > (e.g. via optional arguments) use Lisp-readable frame and window states. > > IOW, make it simple to persist such configurations. > > With window states I tried to approximate window configurations as close > as possible. I don't know enough about frames to do the same for them. > I bet that currently Juanma knows best whether this can be done in some > reasonable way. Yes, I am hoping exactly that. His work with desktop.el will apparently use Lisp-readable representations of sets of frames. I hope this will be applied/extended to the frame-configuration functions, so we can optionally get Lisp-readable frame configurations (with the same properties and interfaces as we have now). E.g., a frame config would continue to look like this, even when Lisp-readable: (frame-configuration FRAME+WINDOW-CONFIG...) where FRAME+WINDOW-CONFIG would be a Lisp-readable representation of a frame (a set of frame parameters, preferably at least the same ones recorded now) plus the frame's window configuration. And likewise for window configurations. We have `window-state-(get|put)', but I would also like to see Lisp-readable window configurations. IOW, wrap with (window-configuration...) what `window-state-get' with non-nil WRITABLE arg returns. E.g.: (window-configuration (((min-height . 4) (min-width . 10) (min-height-ignore . 2) (min-width-ignore . 5) (min-height-safe . 1) (min-width-safe . 2)) leaf (last . t) (total-height . 63) (total-width . 112) (normal-height . 1.0) (normal-width . 1.0) (buffer "foobar.el" (selected . t) (hscroll . 0) (fringes 0 0 nil) (margins nil) (scroll-bars 21 3 t nil) (vscroll . 0) (dedicated) (point . 426354) (start . 424331)))) Let me know if you (e.g. Juanma) prefer that I file this as a separate bug (enhancement request). If so, I will, repeating what I've said here. Thanks to both of you for bring window and frame states to the Lisp world. On that subject, I would like to see either: a. these structures documented, i.e., the structure advertised as such, or b. access functions defined for their parts. IOW, either an open, advertised structure or a black box but providing advertised ways to get at the various components. ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 14:49 ` Drew Adams @ 2013-07-28 16:57 ` Juanma Barranquero 2013-07-28 18:56 ` Drew Adams 2013-07-28 19:53 ` Josh 2013-07-29 7:54 ` martin rudalics 1 sibling, 2 replies; 21+ messages in thread From: Juanma Barranquero @ 2013-07-28 16:57 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 On Sun, Jul 28, 2013 at 4:49 PM, Drew Adams <drew.adams@oracle.com> wrote: > Yes, I am hoping exactly that. His work with desktop.el will apparently use > Lisp-readable representations of sets of frames. I hope this will be > applied/extended to the frame-configuration functions, so we can optionally > get Lisp-readable frame configurations (with the same properties and > interfaces as we have now). I think frame configurations are a bit underdocumented. Also, I'm not sure what do they record and how that differs of what I've had to implement for desktop.el (other than the fact that with frame configurations you cannot restore a deleted frame, and you can with desktop frame-states). In particular, according to current-frame-configuration's docstring: Its car is `frame-configuration'. Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG), where FRAME is a frame object, ALIST is an association list specifying some of FRAME's parameters, and WINDOW-CONFIG is a window configuration object for FRAME." - FRAME, as a frame object, can not be serialized to disk. Serializing it means serializing its contents and attributes, as I try to do in desktop.el. - ALIST specifies "some of FRAME's parameters", but it doesn't say which ones, or the criteria used to select them, or why these parameters are important and not others. - WINDOW-CONFIG is also not serializable, but Martin's window-state-(get|put) does something similar. So, what do you expect of "Lisp-readable frame configurations"? A Lisp readable frame configuration is not very different of a desktop frame-state, and any function that serializes it will necessarily do something similar to desktop-save-frames (details of output format can vary, of course). Which differences are you're interested in? (Other than the currrent API of desktop-save-frames being currently not very reuse-friendly, I mean.) IIUC, what you would do is, either add parameters to the current frame-configuration functions to obtain a serializable config, or add a serialize-frame-config function. Isn't that more or less what I've been doing? If there is information that frame-configuration saves and desktop-save-frames does not, and is information that can be meaningfully restored in another Emacs session, we can discuss adding it. > E.g., a frame config would continue to look like this, even when > Lisp-readable: > > (frame-configuration FRAME+WINDOW-CONFIG...) > > where FRAME+WINDOW-CONFIG would be a Lisp-readable representation of a frame > (a set of frame parameters, preferably at least the same ones recorded now) > plus the frame's window configuration. I see your little trick here ;-) A frame configuration is not the configuration of a frame, but of all existing frames. So a serialized frame configuration would be (frame-configuration (FRAME+WINDOW-CONFIG)...) and that's just syntactic sugar over what a desktop frame-state currently is: ((FRAME-PARAMS . WINDOW-STATE)...) > Let me know if you (e.g. Juanma) prefer that I file this as a separate > bug (enhancement request). If so, I will, repeating what I've said here. No, I just want to understand what is being requested. In other words, the API that does not exist currently and you'd like to see. > a. these structures documented, i.e., the structure advertised as such, or > b. access functions defined for their parts. I'd like to see that, too. > IOW, either an open, advertised structure or a black box but providing > advertised ways to get at the various components. As previously discussed, in private and in my last emacs-devel message, I'm open to that but I don't think that providing an API to serialize individual frames makes much sense. But ways to make desktop-save-frames more open and accesible? Definitely I'm in. J ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 16:57 ` Juanma Barranquero @ 2013-07-28 18:56 ` Drew Adams 2013-07-29 2:14 ` Juanma Barranquero 2013-07-29 7:55 ` martin rudalics 2013-07-28 19:53 ` Josh 1 sibling, 2 replies; 21+ messages in thread From: Drew Adams @ 2013-07-28 18:56 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 14964 Let me know if you think I've left something out. > In particular, according to current-frame-configuration's docstring: > Its car is `frame-configuration'. > Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG), > where > FRAME is a frame object, > ALIST is an association list specifying some of FRAME's parameters, and > WINDOW-CONFIG is a window configuration object for FRAME." > > - FRAME, as a frame object, can not be serialized to disk. Serializing > it means serializing its contents and attributes, as I try to do in > desktop.el. > - ALIST specifies "some of FRAME's parameters", but it doesn't say > which ones, or the criteria used to select them, or why these > parameters are important and not others. > - WINDOW-CONFIG is also not serializable, but Martin's > window-state-(get|put) does something similar. > > So, what do you expect of "Lisp-readable frame configurations"? In brief: Tighten it up. Harmonize the new readable frame & window data structures with the existing non-readable frame and window configuration structures. Enable code to use them the same way. Offer explicit readable frame and window configs whose contents and structure are as compatible as possible with the current, non-readable ones. Some existing code that uses such configs would then just work, and future code too would use structures that say what they are. I don't know which frame parameters are included in ALIST. What I would like is that, if possible, those that are included currently in a non-readable frame config are also included in a readable one. FRAME itself would have to be dropped (since it is a frame object). The FRAME is useful only to code that expects a live frame. Clearly, if a readable frame config is read then it would be used to either create a new frame or to try to reuse an existing frame (e.g., in a new session) that best "fits" the recorded info. The frame name is anyway among the parameters in ALIST. I don't think we can do better than this: drop FRAME - preferably use a placeholder such a nil for it. Except that we might be able to include some frame parameters that ALIST leaves out, perhaps in the form of a second alist (to separate the two sets of parameters, so the original set is identifiable, if that is important). If we do that then ALIST would hopefully be the same as for a non-readable frame config. I don't know which parameters you include now (e.g., for Desktop) that are not included in ALIST. I have no idea whether there is any need for the two sets of recorded parameters (for readable and non-readable) to be different. If not, so much the better. And even if there is a need for them to be different, perhaps there is no real need to keep ALIST compatible, i.e., having the same set for readable and non-readable versions. In that case, all of the frame parameters that you can represent readably could be included in the same ALIST argument, and the form of the frame config would be identical. (The only difference would be the FRAME value - it would be replaced by nil, for instance.) > A Lisp readable frame configuration is not very different of a desktop > frame-state, I think you mean that it is not very different from a desktop SET of frame stateS (plural) - or a state that represents multiple frames. A frame config represents a set of frames (which could of course be a singleton set), not just a single frame. > and any function that serializes it will necessarily do > something similar to desktop-save-frames (details of output format can > vary, of course). Yes, of course. It's all about factoring and generalizing: the focus is on representing an arbitrary set of frames, not on saving a desktop. The form of the result would be similar to the non Lisp-readable frame config: a list with `frame-configuration' as car, a nil FRAME as cadr (for example), an ALIST of the traditional or standard frame parameters (i.e., the same ones), and a readable version of the frame's window configuration. That would (if we think it is important to separate these) be followed by any additional frame parameters that are not recorded for the non Lisp-readable frame config. Or alternatively, if it is not important to keep those separate (identifiable as such), then just include them in ALIST. If all recorded frame parameters are in ALIST, then the only differences from a non-readable frame config are (a) a nil FRAME (or some other convention for FRAME) and (b) the fact that each component is readable. > Which differences are you're interested in? (Other > than the currrent API of desktop-save-frames being currently not very > reuse-friendly, I mean.) See above. Doing this might also mean that we would want to leverage it in the desktop.el code at some point - dunno. In any case, some code factoring in desktop.el would be helpful anyway, as we've discussed. It is not the first priority for desktop.el, perhaps, but it will be good if it is done at some point. > IIUC, what you would do is, either add parameters to the current > frame-configuration functions to obtain a serializable config, Yes, that is what I mentioned: an optional parameter 'WRITABLE, for instance, similar to what Martin did for `window-state-get'. (WRITABLE is actually READABLE, in my book, but either name is OK.) E.g. (current-frame-configuration t) would return a writable & readable frame configuration. > or add a serialize-frame-config function. That too would be OK, but why bother to first create a non-readable frame config and then serialize it? It would be good to have such a serialize-frame-config function anyway, for cases where you already have a non-readable frame config. But I think it would be good for a function like `current-frame-configuration' to be able to create a readable config directly too. > Isn't that more or less what I've been doing? Not explicitly, IIUC. The desktop code does not use, and does not provide for, readable frame configurations. And the `window-state-*' functions do not explicitly provide for readable window configurations. Consider something like this, for example: (defun readable-window-config (window-configuration) "Return a Lisp-readable representation of WINDOW-CONFIGURATION. The form is (window-configuration FRAME-NAME . ROOT-WINDOW-STATE)." ;; Record the name of the frame and its root window state. (let ((winfr (window-configuration-frame window-configuration))) `(window-configuration ,(frame-parameter winfr 'name) . ,(window-state-get (frame-root-window winfr) 'WRITABLE)))) Just one possibility, as an illustration of what I mean. > If there is information that frame-configuration saves and > desktop-save-frames does not, and is information that can be > meaningfully restored in another Emacs session, we can discuss > adding it. I'm not aware of any, and I have not looked. The point is not additional info but the form of the packaged info. The aim for this would be to provide standard, readable frame and window config structures. Using a defstruct would also be OK, but then the form would be even more different from a (current) non-readable frame config, for instance. I would not oppose using a defstruct for both readable and non-readable. A defstruct has some advantages. > > E.g., a frame config would continue to look like this, even when > > Lisp-readable: (frame-configuration FRAME+WINDOW-CONFIG...) > > > > where FRAME+WINDOW-CONFIG would be a Lisp-readable representation > > of a frame (a set of frame parameters, preferably at least the > > same ones recorded now) plus the frame's window configuration. > > I see your little trick here ;-) Well *I* don't see my little trick. What do you mean? I just tried to write down more or less what I see in an existing frame config: it is just that form, no? Let me know if I'm missing something here. > A frame configuration is not the configuration of a frame, but of > all existing frames. Yes, but more correctly, of any set of frames. Yes, it is created by `current-frame-configuration', which records all existing frames at the time of invocation. But it does not necessarily continue to represent all of the existing frames. > So a serialized frame configuration would be > (frame-configuration (FRAME+WINDOW-CONFIG)...) Sorry, I don't understand that at all. Why introduce another list level? It would be just what I wrote, I think: (frame-configuration FRAME+WINDOW-CONFIG...) The only difference would be in the representation of FRAME+WINDOW-CONFIG. It would be a readable representation of a frame, including its window configuration. > and that's just syntactic sugar over what a desktop frame-state > currently is: ((FRAME-PARAMS . WINDOW-STATE)...) Granted, but it is sugar that would let code use the result as it now uses a non-readable frame config. That's the point: use frame configs. If we need to change something in the definition of a frame config, so that it includes more or less info than now, then so be it. But the point is to have a standard structure that code can use and manipulate. That is already the case currently, with the exception that it the structure components are not readable/writable. You can currently get the frame parameters (those that are recorded) or the window config from any frame in the config and then do something with them. You can even construct a new frame config (assuming you know which parameters to record): each frame is recorded as just a list of a frame, (some of) its parameters, and a window config. You can augment an existing frame config, adding another frame representation, etc. Clearly, a defstruct representation might be better, and I don't oppose that. But if we did that then it might be nice to create a wrapper level that enables old code that expects the traditional form (a list) to continue to work. A nice-to-have more than a requirement, I guess. > No, I just want to understand what is being requested. In other > words, the API that does not exist currently and you'd like to see. See above for some more info. In sum, provide aalternative, Lisp-readable representations of both frame configs and window configs, and update the functions that use/create such configs to also use/create the readable form (creating a readable config would be optional via an optional `WRITABLE parameter). > > a. these structures documented, i.e., the structure advertised as > > such, or > > b. access functions defined for their parts. > > I'd like to see that, too. > > > IOW, either an open, advertised structure or a black box but > > providing advertised ways to get at the various components. > > As previously discussed, in private and in my last emacs-devel > message, I'm open to that but I don't think that providing an API to > serialize individual frames makes much sense. But ways to make > desktop-save-frames more open and accesible? Definitely I'm in. I did not mention serializing individual frames here, AFAIK. But I'm actually in favor of that as well, like we do for windows with `window-state-get' + WRITABLE. Why not? (defun readable-frame (frame) "Return a Lisp-readable representation of FRAME. Form is (frame . FRAME-PARAMETERS)." `(frame . ,(desktop--filter-frame-parms (frame-parameters frame) t))) Probably if we did that then we would want to let you specify the frame parameters to record via one or more parameters to the function rather than using `desktop--filter-frame-parms' inside the function body. And for a readable window also, we might want to have a (window...) structure (list), which would just involve putting a wrapper around what is already provided by `window-state-get' (with non-nil WRITABLE). I am not saying that a readable frame config would bother to directly include such readable individual frame representations, with their (frame...) wrappers. I don't see a need for that. Likewise, for a readable window config: no need to include (window...) wrappers. But for manipulating individual readable frames and windows, why not use such a standard representation, which says what it is. Easy to test etc. (Yes, a defstruct is also a possibility here too, but would perhaps be overkill.) ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 18:56 ` Drew Adams @ 2013-07-29 2:14 ` Juanma Barranquero 2013-07-29 23:56 ` Drew Adams 2013-07-29 7:55 ` martin rudalics 1 sibling, 1 reply; 21+ messages in thread From: Juanma Barranquero @ 2013-07-29 2:14 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 On Sun, Jul 28, 2013 at 8:56 PM, Drew Adams <drew.adams@oracle.com> wrote: > In brief: > > Tighten it up. Harmonize the new readable frame & window data > structures with the existing non-readable frame and window > configuration structures. Enable code to use them the same way. > > Offer explicit readable frame and window configs whose contents and > structure are as compatible as possible with the current, non-readable > ones. Some existing code that uses such configs would then just work, > and future code too would use structures that say what they are. The more I think about the whole issue, the less I agree with this point. I think the superficial similarities between frame configurations and desktop's frame-states hide the fact that their goals are deeply different. Frame configurations: - Are low level (coded in C). - Not flexible (they have basically two ops, current-frame-configuration and set-window-configuration; frame-configuration-to-register seems an afterthought). - Intended as an API for programmers, to wrap changes to window and frame configs that will be undone (as in a unwind-protect, for example). - Opaque; not supposed to be modified or played with other than from their get/set functions. - Non-serializable; they are intended for short-term use in the same session they were created (they contain references to live objects). - Relatively oriented to one frame or simple frame setups (they are unable to recreate deleted frames, for example). Frame states: - Are high level (coded in Elisp) - Designed to be flexible: hooks, filters, etc. to modify what is saved and how. - Intended as a UI tool for humans (to save the desktop). - Not very well documented yet, but not opaque (again: filters, hooks, etc.) - Serializable by definition; their very purpose is to be used in a new session. - Able to recreate and manipulate complex frame configurations (including deleted frames). There are a few more differences, of course. For example, frame-configurations have a clear API, while frame-states currently do not (I have fixing that as a short term goal). I don't really see the point of trying to make frame-states more similar to frame-configurations, or to make a future serializable frame-configuration similar to frame-states. They are not going to be used in the same way, or by the same functions. It does not make sense to convert a frame-state into a frame-configuration and feed it back to set-frame-configuration. If you want to use frame-states, just use them. > I don't know which frame parameters are included in ALIST. What I > would like is that, if possible, those that are included currently in > a non-readable frame config are also included in a readable one. Most are. Of those that do not: - parent-id, window-id: does not make sense to save them, you cannot restore them. - buried-buffer-list, buffer-list: perhaps, but that's a bit more complex and it's not clear yet that it is very useful. - name: it could be saved, but then assigning it sets explicit-name to t and it stops being dynamic. A workaround could be found if someone presents a convincing use case. - font-backend: I'm removing it because it's rare setting a font backend explicitly for a frame, but it would be harmless to allow it to be saved. > I think you mean that it is not very different from a desktop SET of > frame stateS (plural) - or a state that represents multiple frames. Yes, I'm calling what desktop saves a "frame-state", though it is the state of a set of frames. Like a frame-configuration is the state of several frames, not just one. > Yes, of course. It's all about factoring and generalizing: the focus > is on representing an arbitrary set of frames, not on saving a desktop. I partially agree; a frame-state can be useful even if not saved persistently. OTOH, though frame-states support recording a partial list of frames, they are a global operation. They are not designed for mix&match of different sets. Saving a frame-state is inherently global; it requires information about all frames, to be able to keep minibuffer relationships and to set the default minibuffer frame (which is required to be able to correctly restore minibufferless frames). The more you slice & dice the existing frames into different frame-states and try to restore them one upon another, the more likely is you'll hit trouble. Also, I have yet so see a use case that does not involve saving all (or almost all) existing frames; going from frame state A to B to C to E and back to any one of them looks useful. Fragmenting A into A1, A2, A3, A4 and then wanting to restore just A1 and A3 seems less useful to me. Also, frame-states *do* have some focus on saving a desktop. They are designed to survive as faithfully as possible being restored in a tty session and back into a GUI session, for example. That means that they can sometimes contain information (in the form of desktop--X parameters) that does not reflect the current state of any frame, but the future state of a frame if it is ever again restored into a GUI session. > In any case, some code > factoring in desktop.el would be helpful anyway, as we've discussed. > It is not the first priority for desktop.el, perhaps, but it will be > good if it is done at some point. Agreed. > E.g. (current-frame-configuration t) would return a writable & readable > frame configuration. That could be useful, but, as discussed above, I just think that its result is just not a frame-state (not implementation-wise, of course, but goal-wise). > Not explicitly, IIUC. The desktop code does not use, and does not > provide for, readable frame configurations. Yes. They will, if possible. > And the `window-state-*' functions do not explicitly provide for > readable window configurations. Consider something like this, for > example: > > (defun readable-window-config (window-configuration) > "Return a Lisp-readable representation of WINDOW-CONFIGURATION. > The form is (window-configuration FRAME-NAME . ROOT-WINDOW-STATE)." > ;; Record the name of the frame and its root window state. > (let ((winfr (window-configuration-frame window-configuration))) > `(window-configuration > ,(frame-parameter winfr 'name) > . ,(window-state-get (frame-root-window winfr) 'WRITABLE)))) What if the frame is dead? (frame-parameter winfr 'name) => nil (frame-root-window winfr) => error > Using a defstruct would also be OK, but then the form would be even > more different from a (current) non-readable frame config, for > instance. I would not oppose using a defstruct for both readable > and non-readable. A defstruct has some advantages. Yes, but it is currently a bit of overkill. > Well *I* don't see my little trick. What do you mean? > I just tried to write down more or less what I see in an existing > frame config: it is just that form, no? Let me know if I'm missing > something here. Yes, sorry. I missed the ... after FRAME+WINDOW-CONFIG :-) > Yes, but more correctly, of any set of frames. Yes, it is created by > `current-frame-configuration', which records all existing frames at > the time of invocation. But it does not necessarily continue to > represent all of the existing frames. The problem is that it doesn't even continue to represent all existing frames at the time of invocation. Only these that are still alive. As I said above, the frame configuration interface doesn't seem oriented to slice & dice, but to save & restore full sets, and particularly to relatively short term save/do-something-that-can-affect-windows&frames/restore operations. > Sorry, I don't understand that at all. Why introduce another list > level? It would be just what I wrote, I think: > (frame-configuration FRAME+WINDOW-CONFIG...) Yes, sorry (again). > Granted, but it is sugar that would let code use the result as it > now uses a non-readable frame config. That's the point: use frame > configs. What kind of code do you think that it is currently using frame configurations and would want to use frame configurations and frame-states in the future? > See above for some more info. In sum, provide aalternative, > Lisp-readable representations of both frame configs and window configs, > and update the functions that use/create such configs to also use/create > the readable form (creating a readable config would be optional via an > optional `WRITABLE parameter). I think that's a worthwhile goal, but I see it as very different of what I need and I'm trying to do. Even if Martin or Stefan or someone else added these readable frame and window configs, they wouldn't substitute frame-states (though I could use them to simplify part of what I'm doing right now, I suppose). > I did not mention serializing individual frames here, AFAIK. But I'm > actually in favor of that as well, like we do for windows with > `window-state-get' + WRITABLE. Why not? > > (defun readable-frame (frame) > "Return a Lisp-readable representation of FRAME. > Form is (frame . FRAME-PARAMETERS)." > `(frame . ,(desktop--filter-frame-parms (frame-parameters frame) t))) You just added desktop--mini to all existing frames. Then you delete a frame, call readable-frame again, and doing so renumber all frames. Then try to restore both frames and likely get conflicts or errors. frame-states partially depend on global state, because their goal is to save and restore *desktops*, and I've done everything I could to make that operation (saving & restoring the desktop) as seamless and painless as possible, even at the cost of making some things less generic. > Probably if we did that then we would want to let you specify the > frame parameters to record via one or more parameters to the function > rather than using `desktop--filter-frame-parms' inside the function body. Yes, that's an example of what I was talking about not being very generic. But that gets messy quite fast, I think. ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 2:14 ` Juanma Barranquero @ 2013-07-29 23:56 ` Drew Adams 2013-07-30 1:05 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 0 siblings, 2 replies; 21+ messages in thread From: Drew Adams @ 2013-07-29 23:56 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 14964 > > Tighten it up. Harmonize the new readable frame & window data > > structures with the existing non-readable frame and window > > configuration structures. Enable code to use them the same way. > > > > Offer explicit readable frame and window configs whose contents and > > structure are as compatible as possible with the current, non-readable > > ones. Some existing code that uses such configs would then just work, > > and future code too would use structures that say what they are. > > The more I think about the whole issue, the less I agree with this point. > > I think the superficial similarities between frame configurations and > desktop's frame-states hide the fact that their goals are deeply > different. > > Frame configurations: > - Are low level (coded in C). Code them in Lisp. > - Not flexible (they have basically two ops, > current-frame-configuration and set-window-configuration; > frame-configuration-to-register seems an afterthought). Add more ops. Make them general. > - Intended as an API for programmers, to wrap changes to window and > frame configs that will be undone (as in a unwind-protect, for > example). They are just structures. You can use them for anything their properties permit. And I am not proposing that they need to stay the same as they are now, in any case, if you feel they are limited. > - Opaque; not supposed to be modified or played with other than from > their get/set functions. Supposed to? Who says so? And just because something is a list or a defstruct, and so you *can* modify it, that does not mean that you *need* to modify it. The uses that Desktop or `frame-configuration-to-register' make of a (new, unified) frame configuration would be different, but they could both use the same structure. And even with just get/set, that is something useful. If the structures were Lisp-readable they would be even more useful (a lot more). Even now you can modify or construct a frame configuration by hand and set the current state to use that configuration using that constructed config. (let* ((f1 (get-a-frame "iii.el")) (p1 (frame-parameters f1)) (w1 (current-window-configuration f1)) (f2 (get-a-frame "my-directory")) (p2 (frame-parameters f2)) (w2 (current-window-configuration f2)) (f3 (get-a-frame "My Emacs Minibuffer")) (p3 (frame-parameters f3)) (w3 (current-window-configuration f3))) (setq new `(frame-configuration (,f1 ,p1 ,w1) (,f2 ,p2 ,w2) (,f3 ,p3 ,w3)))) (set-frame-configuration new) Frame configurations today are not completely opaque. Admittedly, the embedded window-config part is opaque. > - Non-serializable; they are intended for short-term use in the same > session they were created (they contain references to live objects). You are just repeating what exists today for these things. That's my point: let them be (optionally) serializable. I'm asking that the existing frame and window config structures be made transparent (not opaque) and serializable, and that the Desktop and window-state saving code use them. It makes no sense to counter that they are not (yet) serializable and are opaque. Or that the Desktop frame-saving and the `window-state-*' window-saving are not (yet) recognizable, component-accessible structures. That's the whole point of my request: to do just that, bring them together, giving the advantages of each to both. > - Relatively oriented to one frame or simple frame setups (they are > unable to recreate deleted frames, for example). Not to one frame, unless you are referring to a window config, in which case the same applies to `window-state-*' AFAIK. And yes, being able to restore dead frames is an advantage to your code. Let's give it to frame configurations, perhaps optionally. > Frame states: > - Are high level (coded in Elisp) Good. Same would be good for frame configs. They could be based on (parts of) your existing code, for instance. Certainly things should be factored and reused rather than duplicated. > - Designed to be flexible: hooks, filters, etc. to modify what is saved and > how. Again, good. Now add those advantages to frame configs, and add the frame config advantages to Desktop parts. > - Intended as a UI tool for humans (to save the desktop). So are frame configs and window configs used as UI tools. Why do you think we have `frame-configuration-to-register' and then jumping to a frame-config register? > - Not very well documented yet, but not opaque (again: filters, hooks, etc.) Transparent is good. Should be the same for frame & window configs. > - Serializable by definition; their very purpose is to be used in a new > session. Should be added to frame and window configs too. That's a main suggestion I am making. Whether there will still be some need for a C-code version or a non Lisp-readable version of a frame or window config is TBD. I doubt it would be needed. But if someone thinks that access to the actual frame is needed, instead of just sufficient info to re-create it, then we can consider keeping that representation as an alternative one. I, for one, would I think vote for tossing it and moving to only Lisp and only a Lisp-readable representation - essentially the code you've written. Use it as (the basis of) the new implementation of frame configs. Use Martin's `window-state-*' code as (the basis of) the new implementation of window configs. I'm not at all rejecting what you've done. I'm asking that you take it one step further and replace the existing frame & window configs with your implementation. And at that same time, make your code use a standard, recognizable structure with defined accessor functions for its components. IOW, make it usable for frame-config and window-config uses too. > - Able to recreate and manipulate complex frame configurations > (including deleted frames). Also a plus. Also perhaps useful for frame configs. If not, can be ignored or omitted for a frame config. (For purposes of discussion, let's not refer to your frame-set state info as a "frame configuration"; that just makes discussion confusing, since we are discussing also Emacs frame configurations per se.) > There are a few more differences, of course. If there were no differences there would be no need to unify the two. > For example, frame-configurations have a clear API, while frame-states > currently do not (I have fixing that as a short term goal). That's a big part of what my request is. While doing that, if you do it in such a way that we can replace the existing frame-config structures and their APIs, then my request will be fulfilled. I don't really care so much what the final structure looks like or what info it contains. As long as it can be used (together with other state-saving code perhaps) for saving desktops AND it can be used in place of an Emacs frame config (e.g. get a config from the current set of states and set the current set of states from a frame config, as now), I'll be happy. That, and hopefully (a) a recognizing predicate (e.g. `frame-configuration-p') and component accessor functions (for whatever components you end up having that serve both generally (e.g. for frame-config commands/functions) and for desktops. > I don't really see the point of trying to make frame-states more > similar to frame-configurations, or to make a future serializable > frame-configuration similar to frame-states. I can tell you don't. > They are not going to be used in the same way, or by the same > functions. They will hold the same info. Any differences in content today would be removed: any purely desktop-specific stuff would not be part of the frame config. It would be something that can serve for both uses (and other uses as well). > It does not make sense to convert a frame-state into a > frame-configuration and feed it back to set-frame-configuration. Right. That's precisely what I want to avoid. Today, if I want to take the info saved in a frame-config register and persist it and use it in another session, I would need to convert that info to your frame-state form. If I want to put your frame-state info into a register so it can be used with `jump-to-register' to restore/apply it, I would need to convert it to a frame config. And if I want to test whether some list in fact represents frame-state info then what do I do? There is no identifying predicate, such as `frame-configuration-p'. And there is no identifying tag (AFAIK), such as a `frame-config' wrapper or an identifying attribute/keyword. Give us a way to recognize the beast, please. And if I want the equivalent of function `window-configuration-frame' for a `window-state-*' saved state, what do I do? Accessor functions, please. > If you want to use frame-states, just use them. See above. I want to use them where today I would use frame and window configs. And yes, I want them to be persistent or persitable (i.e., optional). > > I don't know which frame parameters are included in ALIST. What I > > would like is that, if possible, those that are included currently in > > a non-readable frame config are also included in a readable one. > > Most are. Of those that do not: > > - parent-id, window-id: does not make sense to save them, you cannot > restore them. Then they would be removed. Or if we keep both live-object configs when providing also persistable configs, then they would be ignored for operations of restoring from persisted data. IOW, they should not be a bother. > - buried-buffer-list, buffer-list: perhaps, but that's a bit more > complex and it's not clear yet that it is very useful. > - name: it could be saved, but then assigning it sets explicit-name to > t and it stops being dynamic. A workaround could be found if someone > presents a convincing use case. > - font-backend: I'm removing it because it's rare setting a font > backend explicitly for a frame, but it would be harmless to allow it > to be saved. Any impedance mismatch can be handled by just using a lowest common denominator for the common structure. If additional things are needed for a given side (e.g. Desktop or in-memory/same-session uses) then such things can either be included and ignored or excluded and handled separately by the different using software. > > I think you mean that it is not very different from a desktop SET of > > frame stateS (plural) - or a state that represents multiple frames. > > Yes, I'm calling what desktop saves a "frame-state", though it is the > state of a set of frames. Like a frame-configuration is the state of > several frames, not just one. Not a great name, but the name is not the most important thing now. > > Yes, of course. It's all about factoring and generalizing: the focus > > is on representing an arbitrary set of frames, not on saving a desktop. > > I partially agree; a frame-state can be useful even if not saved > persistently. Well, there's one thing we agree on. And perhaps we agree that the state of a set of frames can be useful even if it is saved. ;-) Now just what needs to be in such a state in each case is open and likely to be somewhat different. That's not the end of the world. What is needed for set/get during a session might well be different from what is needed for save/restore across sessions. And perhaps the set of frames that is a reasonable unit would be different as well. The point is that there is some info, in fact a lot, I suspect, that is in common. And there are some uses/operations that are also in common. That should be plenty to serve as a basis for finding common ground and factoring it out to serve both use cases. > OTOH, though frame-states support recording a partial > list of frames, they are a global operation. I can see that. But they could also serve a need that did not have that additional requirement. The fact that they can save more and do more does not preclude the ability to use them for something less as well. > They are not designed for mix&match of different sets. Maybe they should be, at some point. Dunno. But that is likely beside the point now. Frame configurations are also not mix&match. The set of all current frames is saved and restored. OK, not dead frames etc. But that's a limitation that could be fixed, e.g., using some of your code. > Saving a frame-state is inherently global; (Ouch; that is such a bad name. It misleads me each time I read it into thinking you are talking about the state of a frame, instead of the state of all of the frames.) > it requires information about all frames, to be able to keep > minibuffer relationships and to set the default minibuffer frame > (which is required to be able to correctly restore minibufferless > frames). See above. I said I can understand that. But as the French like to say, "That which can do more can also do less." > The more you slice & dice the existing frames into different > frame-states and try to restore them one upon another, the more likely > is you'll hit trouble. So let's not do that. > Also, I have yet so see a use case that does > not involve saving all (or almost all) existing frames; going from > frame state A to B to C to E and back to any one of them looks useful. > Fragmenting A into A1, A2, A3, A4 and then wanting to restore just A1 > and A3 seems less useful to me. That sounds OK to me. That is aligned with frame configs too, AFAIK. I can imagine wanting to be able to set a single frame's state to some saved state, modulo loss of info about some of things you mentioned. IOW, you can do some things that could be useful, even if you might not be able to do everything imaginable. I already have code that lets you pick up properties from a given frame interactively and "paste" them onto another frame. This would be an extension of that. But if you don't imagine such a possibility that's OK too. Let's limit things to a frame config (or frame-set state or whatever) representing a snapshot of the global state: all frames (dead and alive, whatever). > Also, frame-states *do* have some focus on saving a desktop. They are > designed to survive as faithfully as possible being restored in a tty > session and back into a GUI session, for example. That use would be kept, of course. If some of the info necessary for that is not useful for other uses such as what we use frame configs for today, then that info could alternatively be kept in a separate data structure (for desktop only, if there is no other use for it). I don't mean that we need to limit what a "new-style" frame config can do or be used for to what today's frame configs can do or be used for. I mean only that if, as you suggest, there are some things that Desktop needs to save for its use of frames that you think will never have any use outside Desktop, then fine, let's leave those things out of the new-style frame config but keep them for Desktop, separately. > That means that they can sometimes contain information (in the form > of desktop--X parameters) that does not reflect the current state of > any frame, but the future state of a frame if it is ever again restored > into a GUI session. OK. Dunno whether that fits into the description of my last paragraph or not. If you think it is stuff that will never serve outside Desktop then it does. If not, perhaps it should be included in a new-style frame config. > > E.g. (current-frame-configuration t) would return a writable & > > readable frame configuration. > > That could be useful, but, as discussed above, I just think that its > result is just not a frame-state (not implementation-wise, of course, > but goal-wise). I don't argue that it is. I don't argue that you can just take the existing thing you call a frame-state (a state representing the state of all frames) and use it as a new-style frame config. I expect that there will some stuff to exclude from the frame config and keep only in Desktop. > > Not explicitly, IIUC. The desktop code does not use, and does not > > provide for, readable frame configurations. > > Yes. They will, if possible. Ah, well maybe we will converge. Let's aim to have it replace the existing frame configs then. And let's please make sure such a beast can be easily recognized and its components easily accessed (e.g. by name). If we do that then I'll be a happy camper. (Likewise for window configs.) > > And the `window-state-*' functions do not explicitly provide for > > readable window configurations. Consider something like this, for > > example: > > > > (defun readable-window-config (window-configuration) > > "Return a Lisp-readable representation of WINDOW-CONFIGURATION. > > The form is (window-configuration FRAME-NAME . ROOT-WINDOW-STATE)." > > ;; Record the name of the frame and its root window state. > > (let ((winfr (window-configuration-frame window-configuration))) > > `(window-configuration > > ,(frame-parameter winfr 'name) > > . ,(window-state-get (frame-root-window winfr) 'WRITABLE)))) > > What if the frame is dead? > (frame-parameter winfr 'name) => nil > (frame-root-window winfr) => error It was an illustration of the kind of thing that's needed, not a proposed implementation. I think (hope) you can see that and appreciate that gross level of communication as well. > > Using a defstruct would also be OK, but then the form would be even > > more different from a (current) non-readable frame config, for > > instance. I would not oppose using a defstruct for both readable > > and non-readable. A defstruct has some advantages. > > Yes, but it is currently a bit of overkill. I'm not sure it is. We should have a type predicate and accessor (i.e., slot functions). Those are the main things a defstruct offers. What would be wrong with using a defstruct, concretely ("overkill" doesn't explain much)? > > Yes, but more correctly, of any set of frames. Yes, it is created by > > `current-frame-configuration', which records all existing frames at > > the time of invocation. But it does not necessarily continue to > > represent all of the existing frames. > > The problem is that it doesn't even continue to represent all existing > frames at the time of invocation. Only these that are still alive. As > I said above, the frame configuration interface doesn't seem oriented > to slice & dice, but to save & restore full sets, and particularly to > relatively short term > save/do-something-that-can-affect-windows&frames/restore operations. Agreed. But it can be made to be more flexible. Your code already proves that. It can be made to (e.g., optionally) include dead frames etc. > > Granted, but it is sugar that would let code use the result as it > > now uses a non-readable frame config. That's the point: use frame > > configs. > > What kind of code do you think that it is currently using frame > configurations and would want to use frame configurations and > frame-states in the future? See above. Both code and interactively, saving and restoring the states of the current set of frames can be useful. We can discuss that more if necessary. > > See above for some more info. In sum, provide aalternative, > > Lisp-readable representations of both frame configs and window configs, > > and update the functions that use/create such configs to also use/create > > the readable form (creating a readable config would be optional via an > > optional `WRITABLE parameter). > > I think that's a worthwhile goal, but I see it as very different of > what I need and I'm trying to do. It's different from what you've done so far. But it's related. And it's especially related to your longer-term intention to factor the desktop.el ball of wax into useful and more modular pieces. > Even if Martin or Stefan or someone > else added these readable frame and window configs, they wouldn't > substitute frame-states (though I could use them to simplify part of > what I'm doing right now, I suppose). Yes, you could, I think. That's the upside for desktop.el. The upside more generally is for users (code and people) of today's frame and window configs, which would become better in several ways (persistent, able to restore more, smarter, transparent, Lisp-level, etc.) > > I did not mention serializing individual frames here, AFAIK. But I'm > > actually in favor of that as well, like we do for windows with > > `window-state-get' + WRITABLE. Why not? > > > > (defun readable-frame (frame) > > "Return a Lisp-readable representation of FRAME. > > Form is (frame . FRAME-PARAMETERS)." > > `(frame . ,(desktop--filter-frame-parms (frame-parameters frame) t))) > > You just... [lots of specific description of why this is not the right > implmentation of a `readable-frame' function] See above - it was an illustration of the idea, not an implementation proposal. Gotta go. HTH. Hoping we will end up at least understanding each other. Hoping beyond that that we might find some common ground. And of course thanks again for your work on this stuff (frame support in Desktop, Lisp-level for frame save/restore, etc. ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 23:56 ` Drew Adams @ 2013-07-30 1:05 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 1 sibling, 0 replies; 21+ messages in thread From: Juanma Barranquero @ 2013-07-30 1:05 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 On Tue, Jul 30, 2013 at 1:56 AM, Drew Adams <drew.adams@oracle.com> wrote: >> Frame configurations: >> - Are low level (coded in C). > > Code them in Lisp. No, not me. I'm not interested in frame configurations. >> - Not flexible (they have basically two ops, >> current-frame-configuration and set-window-configuration; >> frame-configuration-to-register seems an afterthought). > > Add more ops. Make them general. Same answer. >> - Opaque; not supposed to be modified or played with other than from >> their get/set functions. > > Supposed to? Who says so? Their API says so. Their limited options say so. The fact that they are hardly ever used (search the sources). > It makes no sense to counter that they are not (yet) serializable and > are opaque. Or that the Desktop frame-saving and the `window-state-*' > window-saving are not (yet) recognizable, component-accessible > structures. That's the whole point of my request: to do just that, > bring them together, giving the advantages of each to both. There is no "both". They are not the same thing. They are somewhat similar, and that's all. > So are frame configs and window configs used as UI tools. Why do you > think we have `frame-configuration-to-register' and then jumping to a > frame-config register? Because there was no other alternative, and because once you had current-frame-configuration and set-frame-configuration, the -register variants were low-hanging fruit. > I, for one, would I think vote for tossing it and moving to only Lisp and > only a Lisp-readable representation - essentially the code you've written. > Use it as (the basis of) the new implementation of frame configs. Use > Martin's `window-state-*' code as (the basis of) the new implementation of > window configs. No, I don't think so. (let ((current (current-frame-configuration))) (unwind-protect (some-code) (set-frame-configuration current))) is always going to be faster than my code, and useful for `with-*' type macros. That's the whole point of what I'm saying: they are different things. They only seem similar. I think the logical thing to do, assuming my frame-state works and people finds it useful and reliable on the long term, is moving uses of frame configs to frame-states and let frame configs work for what they were intended to do: low-level temporary frame manipulation. There's no need to conflate their APIs. They will never be interchangeable. > I'm not at all rejecting what you've done. I'm asking that you take it > one step further and replace the existing frame & window configs with > your implementation. Too son. Let's talk about this in a few years. > And at that same time, make your code use a standard, recognizable > structure with defined accessor functions for its components. Yes. > IOW, make > it usable for frame-config and window-config uses too. No. > I don't really care so much what the final structure looks like or what > info it contains. As long as it can be used (together with other > state-saving code perhaps) for saving desktops Yes. > AND it can be used in > place of an Emacs frame config (e.g. get a config from the current > set of states and set the current set of states from a frame config, as > now), I'll be happy. No. Though I'm sorry to make you unhappy :-( > Right. That's precisely what I want to avoid. Today, if I want to take > the info saved in a frame-config register and persist it and use it in > another session, I would need to convert that info to your frame-state > form. If I want to put your frame-state info into a register so it can > be used with `jump-to-register' to restore/apply it, I would need to > convert it to a frame config. Then let's make frame-states register-jumpy-friendly. > And if I want to test whether some list in fact represents frame-state > info then what do I do? There is no identifying predicate, such as > `frame-configuration-p'. And there is no identifying tag (AFAIK), such > as a `frame-config' wrapper or an identifying attribute/keyword. > Give us a way to recognize the beast, please. Done. > And if I want the equivalent of function `window-configuration-frame' > for a `window-state-*' saved state, what do I do? Accessor functions, > please. Sorry, that does not make much sense. You can ask `(window-configuration-frame CONFIG) because the windows *and* the frame exist. But you can manipulate a frame-state without making the frame exist, and also, once the frame exists, the frame-state does not contain any pointer to it (it does not contain live objects, ever). Aside: In fact, currently you could implement that with a frame state (i.e., asking a frame state about the frame, because the code I'm writing now ads a persistent parameter frame-state-id, so once restored, frames will always be identifiable; but as a general concept, frame-states are not directly related to real, live frame objects; they are serialization objects only). > Not a great name, but the name is not the most important thing now. You have perhaps a couple days to propose a new name before I commit my code. Later it will be harder to change it ;-)I > The point is that there is some info, in fact a lot, I suspect, that is > in common. And there are some uses/operations that are also in common. > That should be plenty to serve as a basis for finding common ground and > factoring it out to serve both use cases. I think I've stated my case that I don't agree. Also, that I have no interest in working on frame configs / window configs. > (Ouch; that is such a bad name. It misleads me each time I read it > into thinking you are talking about the state of a frame, instead of the > state of all of the frames.) :-) > I don't mean that we need to limit what a "new-style" frame config can > do or be used for to what today's frame configs can do or be used for. > I mean only that if, as you suggest, there are some things that Desktop > needs to save for its use of frames that you think will never have any > use outside Desktop, then fine, let's leave those things out of the > new-style frame config but keep them for Desktop, separately. Most of these things are not really desktop-specific. If you develop a customized application of frame-states (ahem, whatever the name) and do a (voluntary or accidental) roundtrip through a tty session, you will also want things to be restored correctly, and would be upset if sizes, positions and maximized states were destroyed. > I don't argue that it is. I don't argue that you can just take the > existing thing you call a frame-state (a state representing the state > of all frames) You really hate the name, don't you? ;-) > I expect that > there will some stuff to exclude from the frame config and keep only > in Desktop. Yes, some things. > Ah, well maybe we will converge. Let's aim to have it replace the > existing frame configs then. And let's please make sure such a beast > can be easily recognized and its components easily accessed (e.g. by name). > > If we do that then I'll be a happy camper. (Likewise for window configs.) > It was an illustration of the kind of thing that's needed, not a > proposed implementation. I think (hope) you can see that and appreciate > that gross level of communication as well. I was not criticizing your programming, but pointing out what I've said above: that frame configs and window configs depend on and use the fact that they are dealing with live frames and windows. > I'm not sure it is. We should have a type predicate and accessor (i.e., > slot functions). Those are the main things a defstruct offers. What > would be wrong with using a defstruct, concretely ("overkill" doesn't > explain much)? The predicate is trivial, and the accessors too. A defstruct makes more sense to me if you're going to make use of most of its facilities (copier, type-checking ,print function, etc.). >> You just... [lots of specific description of why this is not the right >> implmentation of a `readable-frame' function] > > See above - it was an illustration of the idea, not an implementation > proposal. Again, I was not criticizing your programming. My point was that desktop-save-frames (now frame-state-save, tomorrow who knows what) has more global impact. Though I'm working on minimizing that. > Hoping beyond that that we might find some common ground. Oh, I'm sure we will. At least, we can agree on a name ;-) Juanma ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 23:56 ` Drew Adams 2013-07-30 1:05 ` Juanma Barranquero @ 2013-07-30 9:13 ` martin rudalics 1 sibling, 0 replies; 21+ messages in thread From: martin rudalics @ 2013-07-30 9:13 UTC (permalink / raw) To: Drew Adams; +Cc: Juanma Barranquero, 14964 >> Frame configurations: >> - Are low level (coded in C). > > Code them in Lisp. Don't even think of it. Such endeavours are only frustrating and will keep you busy for months answering complaints like "Emacs never did that", "My Emacs stopped working" and "I want the old behavior back". martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 18:56 ` Drew Adams 2013-07-29 2:14 ` Juanma Barranquero @ 2013-07-29 7:55 ` martin rudalics 2013-07-29 23:53 ` Drew Adams 1 sibling, 1 reply; 21+ messages in thread From: martin rudalics @ 2013-07-29 7:55 UTC (permalink / raw) To: Drew Adams; +Cc: Juanma Barranquero, 14964 > E.g. (current-frame-configuration t) would return a writable & readable > frame configuration. With configurations you store and restore window positions and sizes in situ. That is, you overwrite (in C) the members of the window structure and rely on the fact that a configuration is an immutable memory object to obtain correct bahavior. A function like `set-window-configuration' does not check whether the object it restores is correct in some sense or has been manipulated after it has been stored. It relies on your hardware to do that. `window-state-put' OTOH is pretty failsafe in this regard because it restores windows via the Lisp split and resize operations. > But the point is to have a standard structure that code can use and > manipulate. That would be clearly fatal as explained above. Changing anything in a frame configuration is strictly forbidden. martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 7:55 ` martin rudalics @ 2013-07-29 23:53 ` Drew Adams 2013-07-30 0:18 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 0 siblings, 2 replies; 21+ messages in thread From: Drew Adams @ 2013-07-29 23:53 UTC (permalink / raw) To: martin rudalics; +Cc: Juanma Barranquero, 14964 > > E.g. (current-frame-configuration t) would return a writable & readable > > frame configuration. > > With configurations you store and restore window positions and sizes in > situ. That is, you overwrite (in C) the members of the window structure > and rely on the fact that a configuration is an immutable memory object > to obtain correct bahavior. A function like `set-window-configuration' > does not check whether the object it restores is correct in some sense > or has been manipulated after it has been stored. It relies on your > hardware to do that. `window-state-put' OTOH is pretty failsafe in this > regard because it restores windows via the Lisp split and resize > operations. > > > But the point is to have a standard structure that code can use and > > manipulate. > > That would be clearly fatal as explained above. Changing anything in a > frame configuration is strictly forbidden. Is there some internal use of Emacs window and frame configurations? If not, i.e., if the only use is by users and Lisp code, using the available commands and other functions, then is there some reason that window and frame configurations should not enjoy the properties you mention that are missing and that are available with `window-state-*'? If not, then can we please unite the two, adding the benefits that you added for `window-state-*' to the others as well? The frame and window configurations that users and Lisp code can obtain from Emacs are at least recognizable as such (via predicates), and their parts are accessible (well, only the frame of a window config is accessible, not any of its other parts, but all parts of a frame config are accessible, AFAICT). The data structure returned by `window-state-get' is not recognizable as such. There is not even a `window-state-p' predicate, let alone documented components. This is the only documentation I have seen - a comment in `window-state-get': ;; The return value is a cons whose car specifies some constraints on ;; the size of WINDOW. The cdr lists the states of the child windows ;; of WINDOW. And there is no documentation of either the car (what constraints? in what form?) or the cdr (what form? what order (if important)?)), beyond that. A proper, documented structure (whether list or defstruct) is what I would like to see instead. And unless there are really some good reasons not to, I would like to see the same structure used by the window-configuration functions (`current-window-configuration', `set-window-configuration', `window-configuration-p', `window-configuration-to-register'). IOW, you say that the window states you use and the window-configuration info are different. OK. How about unifying them? And doing so in such a way that the result presents the advantages of each, as far as possible? The advantages I see for a window or frame configuration are (a) recognizability (a type predicate) and (b) accessibility of its components. (Again, window configurations are inadequate wrt (b), but frame configs provide a reasonable model.) --- I make the same argument/request wrt frame configurations and the new Lisp-readable frame-state information that Juanma is developing. Please give us a recognizable frame-configuration object (by whatever name), and if possible unify it with the existing frame-configuration functions (`current-frame-configuration', `set-frame-configuration', `frame-configuration-p', `frame-configuration-to-register'). Let's not just come up with something new and superior and not leverage it for the existing functions. Use the new code for both, for example, after adding any advantages that the old code might provide and the new does not (e.g., a way of identifying the thing as a frame configuration). I'm sure you can argue that the things are not the same, and perhaps even give a reason why they should not be or cannot be the same. But please think carefully about this and do not just dismiss it. That the two are not yet the same is obvious. That users and Lisp code should not be able to use the same thing for both is not yet clear (to me). Of course, parts that might not apply to one or the other use would be skipped over if just irrelevant in some context. I get the impression from Juanma's mails that there is quite a bit more that is saved with his frame-set saved state (for Desktop) than is included in a frame configuration. He has explained that some info about relations among the current frames is needed, for instance: it is not enough to just save the parameters and root window state for each frame. Fine. Then either some of that additional info might also be useful for a frame configuration, or none of it would. In either case, any such info that would not be useful for a frame config would be left out of it. Desktop would continue to save that info, but it would be separate. Desktop would save most of the frames info in the form of a frame config and the rest of it separately. For example, there are perhaps some frame-realated variables that are relevant when saving the state of all the frames, and perhaps those are not pertinent for a frame config (just guessing). Desktop would save those separately. IOW, we can try to unify the two representations of a set of saved frames (or however you would like to characterize it), but that does not mean that the unified result needs to force either Desktop or the existing frame-config functions into a straitjacket. ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 23:53 ` Drew Adams @ 2013-07-30 0:18 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 1 sibling, 0 replies; 21+ messages in thread From: Juanma Barranquero @ 2013-07-30 0:18 UTC (permalink / raw) To: Drew Adams; +Cc: 14964 On Tue, Jul 30, 2013 at 1:53 AM, Drew Adams <drew.adams@oracle.com> wrote: > I make the same argument/request wrt frame configurations and the new > Lisp-readable frame-state information that Juanma is developing. Please > give us a recognizable frame-configuration object (by whatever name), I'm currently separating the frame-state code into a new package (surprisingly named frame-state.el) which does not depend on desktop.el at all. desktop.el will be a client of it (the main client, I'd say). One of the goals is to make frame-state a bit less dependent on global state, though removing all such is impractical. The new format for frame states is (frame-state PROPLIST (FRAME-STATE WINDOW-STATE)...) where `frame-state' is a symbol, and PROPLIST is a property list. The only defined keyword is :version, which will be 1 and would be increased if the format were modified. Additional properties can be added by the user when creating a frame-state. Two that spring to mind would be :name (a readable name) and :id (a md5 or random key or whatever to simplify comparing two frame-states). FRAME-STATE and WINDOW-STATE are as now: a frame parameter list and the output of window-state-get. > if possible unify it with the existing frame-configuration functions > (`current-frame-configuration', `set-frame-configuration', > `frame-configuration-p', `frame-configuration-to-register'). Not possible. current-frame-configuration has no arguments, just "freezes" the current frame configuration. frame-set-save has at least two arguments (a frame-list to limit the frames being considered, and a filter-alist which will default to frame-state-filter-alist (previously known as desktop-filter-frame-params-alist). I'm in the middle of coding this, so it is possible that I end adding more args. frame-state-restore has still more arguments, to select the restoring behavior that is currently set via desktop-* customizable options (desktop will keep these options, which will be the source of the args, though they don't have to be identical and the correspondence is not necessarily one-to-one; let's see). frame-state-p is trivial: (defun frame-state-p (frame-state) "If FRAME-STATE is a frame-state, return its :version. Else return nil." (and (eq (car-safe frame-state) 'frame-state) (plist-get (cl-second frame-state) :version))) and `frame-state-to-register' should be equally easy. > But please > think carefully about this and do not just dismiss it. That the two are > not yet the same is obvious. That users and Lisp code should not be able > to use the same thing for both is not yet clear (to me). It's not clear to me either, but I see enough differences to remain deeply unconvinced. > I get the impression from Juanma's mails that there is quite a bit more > that is saved with his frame-set saved state (for Desktop) than is included > in a frame configuration. He has explained that some info about relations > among the current frames is needed, for instance: it is not enough to just > save the parameters and root window state for each frame. I wouldn't say "quite a bit more". The minibuffer relationships, and also some frame state (position, size, fullscreen state, font, a few other parameters) which must be protected in case the user restores in a tty. > Desktop would continue to save that info, but it would be separate. > Desktop would save most of the frames info in the form of a frame config > and the rest of it separately. For example, there are perhaps some > frame-realated variables that are relevant when saving the state of all > the frames, and perhaps those are not pertinent for a frame config (just > guessing). Desktop would save those separately. At the moment, the readable frame-config format simply does not exist, so I'm not going to worry about being similar or different to it. Sorry. J ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-29 23:53 ` Drew Adams 2013-07-30 0:18 ` Juanma Barranquero @ 2013-07-30 9:13 ` martin rudalics 2013-07-30 14:17 ` Stefan Monnier 1 sibling, 1 reply; 21+ messages in thread From: martin rudalics @ 2013-07-30 9:13 UTC (permalink / raw) To: Drew Adams; +Cc: Juanma Barranquero, 14964 > Is there some internal use of Emacs window and frame configurations? The main purpose of window configurations is with implementing `save-window-excursion'. > If not, i.e., if the only use is by users and Lisp code, using the > available commands and other functions, then is there some reason that > window and frame configurations should not enjoy the properties you > mention that are missing and that are available with `window-state-*'? Speed, I think. `save-window-excursion' is (unfortunately) used much too often in order to compromise its behavior. Saving and restoring a frame configurations doesn't do any size checking, window splitting, suppression of associated error messages - it does its job as quickly as possible. For this purpose, a stored window configuration inhibits the collection of its window objects so it doesn't have to create them anew. > The data structure returned by `window-state-get' is not recognizable as > such. There is not even a `window-state-p' predicate, let alone documented > components. This is the only documentation I have seen - a comment in > `window-state-get': > > ;; The return value is a cons whose car specifies some constraints on > ;; the size of WINDOW. The cdr lists the states of the child windows > ;; of WINDOW. > > And there is no documentation of either the car (what constraints? in what > form?) or the cdr (what form? what order (if important)?)), beyond that. If I had wanted to document that, I would have added the above text to the doc-string of `window-state-get'. > A proper, documented structure (whether list or defstruct) is what I would > like to see instead. Then please, please write one. We all would have to start from scratch doing that. And you know best what you want to see. > And unless there are really some good reasons not to, > I would like to see the same structure used by the window-configuration > functions (`current-window-configuration', `set-window-configuration', > `window-configuration-p', `window-configuration-to-register'). Where would you like to see that? That's a C structure without any Lisp equivalent. It would have to go to the Window Internals section but that one is far from accurate. Window configurations have been devised to restore a previous frame state in one and the same session. Otherwise they were completely opaque. Window states have been devised to restore a previous frame state in another session and are opaque as well. Looking into such objects, documenting them accurately and providing routines to convert one into the other would be quite beneficial for both - users and developers. But this should be really done by someone who wants to exploit and test the results in actual code. martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-30 9:13 ` martin rudalics @ 2013-07-30 14:17 ` Stefan Monnier 0 siblings, 0 replies; 21+ messages in thread From: Stefan Monnier @ 2013-07-30 14:17 UTC (permalink / raw) To: martin rudalics; +Cc: Juanma Barranquero, 14964 > Window configurations have been devised to restore a previous frame > state in one and the same session. And in the same frame as well: you can't move a window-config from one frame to another. Stefan ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 16:57 ` Juanma Barranquero 2013-07-28 18:56 ` Drew Adams @ 2013-07-28 19:53 ` Josh 2013-07-28 20:33 ` Drew Adams 1 sibling, 1 reply; 21+ messages in thread From: Josh @ 2013-07-28 19:53 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 14964 On Sun, Jul 28, 2013 at 9:57 AM, Juanma Barranquero <lekktu@gmail.com> wrote: > On Sun, Jul 28, 2013 at 4:49 PM, Drew Adams <drew.adams@oracle.com> wrote: > >> Yes, I am hoping exactly that. His work with desktop.el will apparently use >> Lisp-readable representations of sets of frames. I hope this will be >> applied/extended to the frame-configuration functions, so we can optionally >> get Lisp-readable frame configurations (with the same properties and >> interfaces as we have now). > So, what do you expect of "Lisp-readable frame configurations"? A Lisp > readable frame configuration is not very different of a desktop > frame-state, and any function that serializes it will necessarily do > something similar to desktop-save-frames (details of output format can > vary, of course). Which differences are you're interested in? (Other > than the currrent API of desktop-save-frames being currently not very > reuse-friendly, I mean.) There's a very nice library called Workgroups for Windows[0] that can persist window and frame configurations across sessions (and much more, with a few of the more interesting features appearing only in the "Experimental" branch). It might be interesting to look at its approach to these and similar questions. Josh [0] https://github.com/tlh/workgroups.el ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 19:53 ` Josh @ 2013-07-28 20:33 ` Drew Adams 0 siblings, 0 replies; 21+ messages in thread From: Drew Adams @ 2013-07-28 20:33 UTC (permalink / raw) To: Josh, Juanma Barranquero; +Cc: 14964 > https://github.com/tlh/workgroups.el Yes, it is good to point to that, as another example of readable window configurations. You mentioned frame configurations too, but working groups are not, according to what I read in the doc and see in the code, frame configurations. Rather, a workgroup is a set of window configurations for a single frame. From the doc: Q: What's the difference between a "window configuration", a "wconfig" and a "workgroup"? A: A "window configuration" is Emacs' opaque internal representation of most of the state of one frame. A "wconfig" is Workgroups' independent, translucent window configuration object. And a "workgroup" is a named set of multiple wconfigs (one base config, and then a working config for each frame). So yes, this could inform what we do wrt Emacs window configurations. It is also an example of the kinds of things that a library or a user might want to do with persistent window configurations. And it is another argument for having a standard, transparent, readable window-configuration structure (whatever form the implementation might take). ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-28 14:49 ` Drew Adams 2013-07-28 16:57 ` Juanma Barranquero @ 2013-07-29 7:54 ` martin rudalics 1 sibling, 0 replies; 21+ messages in thread From: martin rudalics @ 2013-07-29 7:54 UTC (permalink / raw) To: Drew Adams; +Cc: Juanma Barranquero, 14964 > And likewise for window configurations. We have `window-state-(get|put)', > but I would also like to see Lisp-readable window configurations. IOW, wrap > with (window-configuration...) what `window-state-get' with non-nil WRITABLE > arg returns. E.g.: [...] > Let me know if you (e.g. Juanma) prefer that I file this as a separate > bug (enhancement request). If so, I will, repeating what I've said here. > > Thanks to both of you for bring window and frame states to the Lisp world. > > On that subject, I would like to see either: > > a. these structures documented, i.e., the structure advertised as such, or > b. access functions defined for their parts. > > IOW, either an open, advertised structure or a black box but providing > advertised ways to get at the various components. I won't object your suggestions but please keep in mind that I designed the window state functions to work in two contexts: (1) Restore the window layout of a frame or internal window so it can be replayed within a window of a frame. This makes it possible to easily switch between layouts with side windows (something the IDE gurus wanted) and back. (2) To save and restore frame layouts between sessions. Converting states to configurations and back is a different and pretty hairy task. martin ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2013-07-27 8:18 ` martin rudalics 2013-07-27 19:39 ` Drew Adams @ 2022-04-21 13:42 ` Lars Ingebrigtsen 2022-05-20 2:23 ` Lars Ingebrigtsen 1 sibling, 1 reply; 21+ messages in thread From: Lars Ingebrigtsen @ 2022-04-21 13:42 UTC (permalink / raw) To: martin rudalics; +Cc: 14964 martin rudalics <rudalics@gmx.at> writes: >> The doc doesn't tell you enough about what this function does to be able >> to use it. Compare how? What does a non-nil or nil return value mean? >> Does the order of the two arguments matter? What's going on here? What >> for? > > I never understood the purpose of this function. Does anyone use it? It's used in only one place in-tree: (defun strokes-window-configuration-changed-p () "Non-nil if the `strokes-window-configuration' frame properties changed. This is based on the last time `strokes-window-configuration' was updated." (compare-window-configurations (current-window-configuration) strokes-window-configuration)) Anyway, perhaps it would make sense to rename it to `window-configuration-equal-p'? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#14964: 24.3.50; doc of `compare-window-configurations' 2022-04-21 13:42 ` Lars Ingebrigtsen @ 2022-05-20 2:23 ` Lars Ingebrigtsen 0 siblings, 0 replies; 21+ messages in thread From: Lars Ingebrigtsen @ 2022-05-20 2:23 UTC (permalink / raw) To: martin rudalics; +Cc: 14964, Drew Adams Lars Ingebrigtsen <larsi@gnus.org> writes: > Anyway, perhaps it would make sense to rename it to > `window-configuration-equal-p'? I've now done this in Emacs 29 (and fixed the documentation). -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2022-05-20 2:23 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-07-27 3:14 bug#14964: 24.3.50; doc of `compare-window-configurations' Drew Adams 2013-07-27 8:18 ` martin rudalics 2013-07-27 19:39 ` Drew Adams 2013-07-28 8:40 ` martin rudalics 2013-07-28 14:49 ` Drew Adams 2013-07-28 16:57 ` Juanma Barranquero 2013-07-28 18:56 ` Drew Adams 2013-07-29 2:14 ` Juanma Barranquero 2013-07-29 23:56 ` Drew Adams 2013-07-30 1:05 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 2013-07-29 7:55 ` martin rudalics 2013-07-29 23:53 ` Drew Adams 2013-07-30 0:18 ` Juanma Barranquero 2013-07-30 9:13 ` martin rudalics 2013-07-30 14:17 ` Stefan Monnier 2013-07-28 19:53 ` Josh 2013-07-28 20:33 ` Drew Adams 2013-07-29 7:54 ` martin rudalics 2022-04-21 13:42 ` Lars Ingebrigtsen 2022-05-20 2:23 ` Lars Ingebrigtsen
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).