From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juanma Barranquero Newsgroups: gmane.emacs.bugs Subject: bug#14964: 24.3.50; doc of `compare-window-configurations' Date: Mon, 29 Jul 2013 04:14:04 +0200 Message-ID: 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 X-Trace: ger.gmane.org 1375064117 32250 80.91.229.3 (29 Jul 2013 02:15:17 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 29 Jul 2013 02:15:17 +0000 (UTC) Cc: 14964@debbugs.gnu.org To: Drew Adams Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Jul 29 04:15:17 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 1V3czU-00070M-4R for geb-bug-gnu-emacs@m.gmane.org; Mon, 29 Jul 2013 04:15:16 +0200 Original-Received: from localhost ([::1]:54113 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3czT-0000ro-Jg for geb-bug-gnu-emacs@m.gmane.org; Sun, 28 Jul 2013 22:15:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34350) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3czM-0000rj-D0 for bug-gnu-emacs@gnu.org; Sun, 28 Jul 2013 22:15:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V3czH-0000nG-S4 for bug-gnu-emacs@gnu.org; Sun, 28 Jul 2013 22:15:08 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:60844) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3czH-0000mD-Hd for bug-gnu-emacs@gnu.org; Sun, 28 Jul 2013 22:15:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1V3czG-0002Ar-UR for bug-gnu-emacs@gnu.org; Sun, 28 Jul 2013 22:15:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juanma Barranquero Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 29 Jul 2013 02:15: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.13750640938306 (code B ref 14964); Mon, 29 Jul 2013 02:15:02 +0000 Original-Received: (at 14964) by debbugs.gnu.org; 29 Jul 2013 02:14:53 +0000 Original-Received: from localhost ([127.0.0.1]:55160 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1V3cz6-00029t-GB for submit@debbugs.gnu.org; Sun, 28 Jul 2013 22:14:53 -0400 Original-Received: from mail-ea0-f173.google.com ([209.85.215.173]:44954) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1V3cz4-00029S-84 for 14964@debbugs.gnu.org; Sun, 28 Jul 2013 22:14:51 -0400 Original-Received: by mail-ea0-f173.google.com with SMTP id g10so2633199eak.4 for <14964@debbugs.gnu.org>; Sun, 28 Jul 2013 19:14:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=qJDfXd2yoKdyhApfamqosKhVjKRCf1NCq1RQVY+19YU=; b=C+JzmrZ/aP4gUP2IouRJ02qF313qkmf7Xs1ZOe27jP/pHO6axntS7Rww/vBundM6fn LmZ6PUmNFrAofdbSBpa7h4WQLWlblvSjN74HDKBIJy0IYXBxgtoCuwH3m9hKhtJ+Ajzt 0kiJs1NrAYv7Wwu+9VZYR5AntCrhW41Ugnst7glaBcOlbZdn81mO4LW/95uRCl4vSCeq THq+mvhtpfcIESHJhz2H9ZTXLJlYY78E4RnqYIeIphhC/8h0+4K3/NLQezcqnVwH/Gf5 GyDwf2rhPPKYGxhzEgZO1OprjinushDDWM/OqliLWsXxjAJoTnurbXqspmq9jlB44Q30 Wjlw== X-Received: by 10.15.111.69 with SMTP id ci45mr7596043eeb.14.1375064084355; Sun, 28 Jul 2013 19:14:44 -0700 (PDT) Original-Received: by 10.15.23.70 with HTTP; Sun, 28 Jul 2013 19:14:04 -0700 (PDT) In-Reply-To: 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:76746 Archived-At: On Sun, Jul 28, 2013 at 8:56 PM, Drew Adams 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.