From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.bugs Subject: bug#14964: 24.3.50; doc of `compare-window-configurations' Date: Mon, 29 Jul 2013 16:56:48 -0700 (PDT) Message-ID: <415a3d22-c36e-4736-bae1-877b19c0e658@default> References: <51e98138-a20c-48ad-bea2-de67eb6b04b5@default> <51F3826F.9060600@gmx.at> <51F4D8FF.6000703@gmx.at> <25701584-34ff-4754-8d10-7f2d223205ac@default> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1375142305 18316 80.91.229.3 (29 Jul 2013 23:58:25 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 29 Jul 2013 23:58:25 +0000 (UTC) Cc: 14964@debbugs.gnu.org To: Juanma Barranquero Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Jul 30 01:58:26 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1V3xKa-0002Pc-J1 for geb-bug-gnu-emacs@m.gmane.org; Tue, 30 Jul 2013 01:58:24 +0200 Original-Received: from localhost ([::1]:42060 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3xKa-00062Y-9X for geb-bug-gnu-emacs@m.gmane.org; Mon, 29 Jul 2013 19:58:24 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36087) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3xKN-00060V-II for bug-gnu-emacs@gnu.org; Mon, 29 Jul 2013 19:58:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V3xKE-0000nh-Ta for bug-gnu-emacs@gnu.org; Mon, 29 Jul 2013 19:58:11 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:34431) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3xKE-0000nb-Pk for bug-gnu-emacs@gnu.org; Mon, 29 Jul 2013 19:58:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1V3xKE-00083o-I6 for bug-gnu-emacs@gnu.org; Mon, 29 Jul 2013 19:58:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Drew Adams Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 29 Jul 2013 23:58:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 14964 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 14964-submit@debbugs.gnu.org id=B14964.137514222530852 (code B ref 14964); Mon, 29 Jul 2013 23:58:02 +0000 Original-Received: (at 14964) by debbugs.gnu.org; 29 Jul 2013 23:57:05 +0000 Original-Received: from localhost ([127.0.0.1]:56973 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1V3xJG-00081R-N5 for submit@debbugs.gnu.org; Mon, 29 Jul 2013 19:57:04 -0400 Original-Received: from userp1040.oracle.com ([156.151.31.81]:45375) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1V3xJD-00080e-Ci for 14964@debbugs.gnu.org; Mon, 29 Jul 2013 19:57:01 -0400 Original-Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r6TNuqE9013995 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 29 Jul 2013 23:56:53 GMT Original-Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r6TNunc9011389 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 29 Jul 2013 23:56:51 GMT Original-Received: from abhmt120.oracle.com (abhmt120.oracle.com [141.146.116.72]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r6TNunLu021396; Mon, 29 Jul 2013 23:56:49 GMT In-Reply-To: X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.7 (607090) [OL 12.0.6668.5000 (x86)] X-Source-IP: acsinet21.oracle.com [141.146.126.237] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:76782 Archived-At: > > 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. >=20 > The more I think about the whole issue, the less I agree with this point. >=20 > I think the superficial similarities between frame configurations and > desktop's frame-states hide the fact that their goals are deeply > different. >=20 > 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 a= nd > 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, et= c.) 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. >=20 > Most are. Of those that do not: >=20 > - 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. >=20 > 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. =20 > > 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. >=20 > 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.=20 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=20 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. >=20 > 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. >=20 > 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)))) >=20 > What if the frame is dead? > (frame-parameter winfr 'name) =3D> nil > (frame-root-window winfr) =3D> 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. >=20 > 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. >=20 > 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. >=20 > 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/creat= e > > the readable form (creating a readable config would be optional via an > > optional `WRITABLE parameter). >=20 > 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)= )) >=20 > 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.