
Hi all! This may end up being a long e-mail. Executive summary: 1. PerWorkspace is an inelegant hack with several icky problems: - 'description' is not in the X monad so can't figure out the current workspace - the currently focused workspace might not even be the correct one anyway, in the case of xinerama or message handling. 2. Andrea's LayoutCombinator class and core patch to move the result of the description function into the X monad will help with some but not all of the problems. In particular it still won't work with xinerama. 3. It would be nice to have the PerWorkspace functionality supported in the core, and I have a nice, elegant way to do it. This would fix all the problems. ...The only catch is that it would also require going back to requiring existential Layout wrappers everywhere. =( 4. Well, crap. I had recently been thinking about PerWorkspace and ways to improve it, but hadn't yet gotten around to really doing anything about it. Andrea's new emptyLayout function, and then in particular his reimplementation of PerWorkspace using the new LayoutCombinator framework obviously motivated me to get around to it! So I'd like to explain some of the problems with PerWorkspace and possible future directions. First, the basics: although the xmonad core tracks layouts separately for each workspace, it is not possible to *specify* a different starting layout on a per-workspace basis. Only a single layout may be specified in the XConfig record, and this layout is duplicated across all workspaces on xmonad startup. PerWorkspace attempts to get around this limitation by providing a layout which dynamically decides on which of two sub-layouts to use, based on the current workspace tag. All workspaces still have the same layout, but that one layout acts differently depending on the current workspace. You can see from the beginning that this is something of a hack. This approach has two major limitations, each of which leads to one or more problems. * To find out the current workspace obviously requires access to the X monad. For doLayout and handleMessage this is obviously not a problem. The description method, however, is a pure function. I solved this in a very hackish way before by having a call to doLayout return a modified PerWorkspace layout structure with a cached value remembering which of the two layouts should be used. description could then use this cached value to decide on the description to return. Andrea's current reimplementation of PerWorkspace does not do this caching, which is why the description method is currently broken. I can reimplement this, and the new emptyLayout method will help, but it still feels very inelegant. * A more insidious problem is that it is not possible, in general, for doLayout or doMessage to figure out which workspace they belong to, and hence which layout to use. PerWorkspace currently works by retrieving the tag of the currently focused workspace from the xmonad state, but there are several situations in which doLayout or handleMessage are called on a workspace which is not the currently focused workspace: - If xinerama is in use, doLayout will be called for all the visible workspaces as well as the focused workspace. - Messages can be broadcast to all workspaces, in which case handleMessage will be called for all workspaces, including non-focused or even hidden workspaces. In either of these situations, PerWorkspace may choose the wrong layout. The message problem can be solved by simply passing along any messages to all layouts, without trying to decide on the correct one: it cannot hurt to pass messages to unintended recipients, especially if the unintended recipient layouts will never be used anyway! The xinerama problem seems insoluble, however. PerWorkspace simply cannot work on xinerama because it cannot get the information it needs to decide which layout to use. So, what is the way forward? It looks like I can get PerWorkspace back to its original level of workingness --- thanks to the LayoutCombinator class it will be a lot shorter, but it still won't work with xinerama, and it will still be an ugly, fragile hack. I had been intending to suggest adding support for per-workspace layouts to the xmonad core. After all, xmonad does track and save/restore layouts on a per-workspace basis, so why shouldn't it allow configuring them on a per-workspace basis too? I intended to keep the current layoutHook (specifying the default layout to be used on all workspaces not otherwise specified) as well as adding a new field to the config which would store a list of (workspace tag, layout) pairs. The core modifications necessary to support this are not too hard and end up being fairly elegant -- in fact, I have made these modifications in a local branch. The catch? Having a bunch of layouts in a list like this requires going back to wrapping everything with Layout existentials in user configs! =( This doesn't sound like much fun either. So, I am at something of a loss. Any thoughts or suggestions for moving forward are appreciated! -Brent

On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
2. Andrea's LayoutCombinator class and core patch to move the result of the description function into the X monad will help with some but not all of the problems. In particular it still won't work with xinerama.
I'll read more carefully your interesting message, but I would like to point out that my request to change the description method of the LayoutClass has not been done to fix PerWorkspace but because I argue that description is buggy, since it prevents me to write a LayoutCombinator class and a CombinedLayout instance of the LayoutClass that is general enough to be a ... class. Since, as you and some users noted, the present state of the repository, and of PerWorkspace specifically, is broken, I'm going to push a patch, in the next few hours, that removes the LayoutCombinator class and reverts PerWorkspace to its pristine "PerWorkspace [WorkspaceId] Maybe Bool l1 l2 a" state, at least till when a decision of the description type signature has been taken. (As a side note, I would like to see someone step out to show me I'm plainly wrong with my claim about the relationship between that specific type signature and the expressiveness of a LayoutCombinator class. I wonder whether I'm asking too much). Now I go read the rest more carefully. Let me take the opportunity to thank you for the documentation you are producing on the wiki (and, if I understand correctly something is due somewhere else... a novel!) about the xmonad internals. Ciao Andrea

On 1/31/08, Brent Yorgey
The catch? Having a bunch of layouts in a list like this requires going back to wrapping everything with Layout existentials in user configs! =( This doesn't sound like much fun either.
Could you help me recollect the way it looked in user configs? - , layoutHook = tiled ||| Mirror tiled ||| noBorders Full + , layoutHook = (Layout tiled) ||| (Layout $ Mirror tiled) ||| (Layout $ noBorders Full) Something like this? -- vvv

On Thu, Jan 31, 2008 at 5:17 AM, Valery V. Vorotyntsev
On 1/31/08, Brent Yorgey
wrote: The catch? Having a bunch of layouts in a list like this requires going back to wrapping everything with Layout existentials in user configs! =( This doesn't sound like much fun either.
Could you help me recollect the way it looked in user configs?
- , layoutHook = tiled ||| Mirror tiled ||| noBorders Full + , layoutHook = (Layout tiled) ||| (Layout $ Mirror tiled) ||| (Layout $ noBorders Full)
Something like this?
No, you would only need one wrapper, like , layoutHook = Layout $ tiled ||| Mirror tiled ||| noBorders Full

On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
Hi all!
This may end up being a long e-mail. Executive summary:
1. PerWorkspace is an inelegant hack with several icky problems: - 'description' is not in the X monad so can't figure out the current workspace - the currently focused workspace might not even be the correct one anyway, in the case of xinerama or message handling.
Bret,
perhaps there's something deeper I just don't get, but as far as I
understand your problem comes from the fact that you do not know in
which workspace you're handling a message.
This is a quite trivial patch that just gives you a method for that:
Thu Jan 31 13:42:23 CET 2008 Andrea Rossato

perhaps there's something deeper I just don't get, but as far as I
understand your problem comes from the fact that you do not know in which workspace you're handling a message.
This is a quite trivial patch that just gives you a method for that: Thu Jan 31 13:42:23 CET 2008 Andrea Rossato
* Add handleMessageInWorkspace, a method that knows where to be M ./XMonad/Core.hs +3 M ./XMonad/Operations.hs -2 +2 which adds: handleMessageInWorkspace :: Workspace i (layout a) a -> SomeMessage -> X (Maybe (layout a))
But it's not just about messages; we'd also need doLayoutInWorkspace and emptyLayoutInWorkspace. In particular xinerama support would not work without those. Since PerWorkspace is the only layout that could possibly use this information, adding three new methods to the LayoutClass just for this is almost certainly not the way to go. -Brent

On Thu, Jan 31, 2008 at 12:29:55PM -0500, Brent Yorgey wrote:
But it's not just about messages; we'd also need doLayoutInWorkspace and emptyLayoutInWorkspace. In particular xinerama support would not work without those. Since PerWorkspace is the only layout that could possibly use this information, adding three new methods to the LayoutClass just for this is almost certainly not the way to go.
Ok, so, if I get it right, you are proposing to go back to existential and everything just because you think it is wrong to extend a class, which, I was told, is just something you can extend without breaking what is built upon it. All this because you suppose PerWorspace is the only one that *may* be using a non pure combinator. Well, just today Joachim was asking for something like a combinator, implemented as another hook. Brent, even though I really like your code, I must confess I *totally* disagree with your design principles. Cheers, Andrea

On Thu, Jan 31, 2008 at 1:07 PM, Andrea Rossato < mailing_list@istitutocolli.org> wrote:
But it's not just about messages; we'd also need doLayoutInWorkspace and emptyLayoutInWorkspace. In particular xinerama support would not work without those. Since PerWorkspace is the only layout that could
On Thu, Jan 31, 2008 at 12:29:55PM -0500, Brent Yorgey wrote: possibly
use this information, adding three new methods to the LayoutClass just for this is almost certainly not the way to go.
Ok, so, if I get it right, you are proposing to go back to existential and everything just because you think it is wrong to extend a class, which, I was told, is just something you can extend without breaking what is built upon it.
I do not think it is wrong to extend a class *in general*. What I do think is not very elegant is to add *three new methods* to the LayoutClass (also requiring changes to the xmonad core so that it calls these new methods instead of the old ones), just to support a *single* layout. And no, these methods would not make the LayoutClass more general; this is the only layout I can conceivably think of that would need to know the tag of the workspace in which it is being called. Note I am also not proposing to go back to existential wrappers everywhere, I'm pretty sure I put a sad face next to that in my e-mail. =)
All this because you suppose PerWorspace is the only one that *may* be using a non pure combinator.
It has nothing to do with purity/non-purity. I assume you are referring to the thing with the 'description' method not having a result in the X monad? This is an orthogonal issue; I don't have a strong feeling about it one way or another. It is true that the only layout I have seen that could possibly need this, again, is PerWorkspace. But in any case the *main* point is to get PerWorkspace working with xinerama, which has nothing to do with the type of 'description', but about the need for somehow getting this extra information about what workspace a layout resides in. Regards, -Brent

On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
The catch? Having a bunch of layouts in a list like this requires going back to wrapping everything with Layout existentials in user configs! =( This doesn't sound like much fun either.
This could be solved by introducing a new list-replacement data type that would have encode in its type the types of all its elements. I'm not saying this is pretty, but it's possible. Of course, having different typed workspaces would be a pain also, and the change would permeate throughout xmonad. -- David Roundy Department of Physics Oregon State University

On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much. \begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code} 'selected' is Nothing until we either figure out which workspace the layout is on, or we're forced to render before we figure it out. 'choices' maps workspaceids to desired layouts. 'default' is used when the WorkspaceId isn't in our 'choices' map, or we're forced to render before we know which workspace we're on. Now, the million dollar question: how do we figure out which workspace a layout is on? \begin{code} data YouAreHere = YAH WorkspaceId deriving Typeable instance Message YouAreHere \end{code} Now we just need to arrange for this message to be sent. I see two options: - add a 'startupHook :: X ()' that is executed when xmonad starts. This might be useful for other applications too. A minor issue is that the user will have to edit startupHook and layoutHook to use PerWorkspace successfully. - have the core send YouAreHere messages to each visible workspace during each refresh. This is easier for the user, but it requires adding more to the core. Oh, and once we've done this, description will not need to be in the X monad. Andrea, did you have any other use cases in mind? Cheers, Spencer Janssen

On Thu, Jan 31, 2008 at 01:42:32PM -0600, Spencer Janssen wrote:
On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design.
actually I don't think this is true. I believe that the LayoutClass can be far more expressive that it is now just by adding a couple of trivial methods. I've sent a patch two messages ago. That kind of approach seems to me to be cleaner that yours (which, as far as I get it requires messages going around to know where you are).
Oh, and once we've done this, description will not need to be in the X monad. Andrea, did you have any other use cases in mind?
I don't think I can "prove" you need a description in the X monad to have class level composition, but I've surely sent a case: a CombinedLayout instance where a combined description could not be implemented purely without information loss. I take that as a prove. But if you can implement that combinator over the layout class with your approach, then I think you proved I'm wrong. As I said, I feel my approach (some additional methods) is cleaner probably because I'm just used to it. I'll study yours, but I find it uselessly complicated. Cheers, Andrea

On Thu, Jan 31, 2008 at 09:21:30PM +0100, Andrea Rossato wrote:
On Thu, Jan 31, 2008 at 01:42:32PM -0600, Spencer Janssen wrote:
On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design.
(here, I'm specifically speaking to the issue of PerWorkspace and multi-head)
actually I don't think this is true. I believe that the LayoutClass can be far more expressive that it is now just by adding a couple of trivial methods. I've sent a patch two messages ago. That kind of approach seems to me to be cleaner that yours (which, as far as I get it requires messages going around to know where you are).
As far as I know, there has only been one other proposal that solves the Xinerama issues with PerWorkspace -- adding a WorkspaceId argument to doLayout. I think we've all agreed that isn't so nice. My message proposal is actually very similar -- except that only layouts that care about workspace location need to handle these messages, whereas an extra argument to doLayout must be mentioned in every single layout instance. Have you proposed another implementation that solves the Xinerama issue, and I missed it? Cheers, Spencer Janssen

On Fri, Feb 01, 2008 at 12:22:32AM -0600, Spencer Janssen wrote:
As far as I know, there has only been one other proposal that solves the Xinerama issues with PerWorkspace -- adding a WorkspaceId argument to doLayout. I think we've all agreed that isn't so nice. My message proposal is actually very similar -- except that only layouts that care about workspace location need to handle these messages, whereas an extra argument to doLayout must be mentioned in every single layout instance.
Have you proposed another implementation that solves the Xinerama issue, and I missed it?
Yes you did. You actually did miss quite a lot of the stuff I've been sending recently. You are not the only one, though. As I say I did not propose to change doLayout, but just to change, in runLayout, doLayout with a doLayoutInWorkspace which takes the workspace and calls "doLayout (layout w)". The same for (emptyLayoutInWorkspace w = emptyLayout (layout w) and handleMessage. Did you read this message and the attached patch? http://www.haskell.org/pipermail/xmonad/2008-January/004493.html If a layout may be knowing the workspace it is running on, we could implement a general purpose combinator (my LayoutCombinator class and a general purpose CombinedLayout, implemented on top of the layout class. If we get to class level composition - by changing the description type, we can implement ANY combinator within the layout hook. Combinators, in this case, may be receiving messages and run one, layout, run the other, run both and combine their result, or run none, handle the message, and return a new combinator. This solves xinerama and we can eliminate duplicate code in Choose, NewSelect, ToogleWorskpace, PerWorkspace. As I mention here: http://code.google.com/p/xmonad/issues/detail?id=129 (I answered to your challenge, but you did not to mine!), with my proposal, PerWorkspace implementation would be: instance LayoutCombinator PerWorkspace a where chooser (PerWorkspace wsIds) = do t <- getCurrentTag return $ if t `elem` wsIds then DoFirst else DoSecond Obviously here I'm using class level composition. Can you really claim your implementation would be cleaner? Show me the code, please. I showed mine, which is actually working. That implementation IS ACTUALLY working and has been in xmc repository for a couple of days. Than I had to remove it since I asked for core support and I was told I would not get it. So, I removed it. And I asked you to forget all related patches. Cheers, Andrea

On Fri, Feb 01, 2008 at 07:48:57AM +0100, Andrea Rossato wrote:
That implementation IS ACTUALLY working and has been in xmc repository for a couple of days. Than I had to remove it since I asked for core support and I was told I would not get it.
So, I removed it. And I asked you to forget all related patches.
by any chance, did you happen to read this bug report? http://code.google.com/p/xmonad/issues/detail?id=127 cheers, andrea ps: all this stuff has been documented by me here: http://www.haskell.org/pipermail/xmonad/2008-January/004378.html http://www.haskell.org/pipermail/xmonad/2008-January/004398.html http://www.haskell.org/pipermail/xmonad/2008-January/004400.html http://www.haskell.org/pipermail/xmonad/2008-January/004401.html http://www.haskell.org/pipermail/xmonad/2008-January/004417.html http://www.haskell.org/pipermail/xmonad/2008-January/004424.html http://www.haskell.org/pipermail/xmonad/2008-January/004440.html http://www.haskell.org/pipermail/xmonad/2008-January/004441.html http://www.haskell.org/pipermail/xmonad/2008-January/004442.html http://www.haskell.org/pipermail/xmonad/2008-January/004443.html yesterday's messages omitted. there are some other messages, sent before, documenting the progress of the changes and giving testing example. pps: i'm reading the IRC logs and I see someone is complaining because I would be experimenting with his/her window manager, and that I should keep my stuff in a private repository. from http://code.haskell.org/~dons/irc/xmonad/2008-01-29.txt: 09:26:29 <arossato> still no comments/feedback on the new code I proposed... ... 19:40:10 <arossato> sjanssen dons: did you have a look at my code? 19:41:25 <sjanssen> arossato: a little bit. Feel free to push it to the mainline any time 19:42:02 <dons> yeah, seriously, if you've considered it well, and it only affects config stuff, and you know its not going to break things, go ahead. 19:42:07 <arossato> sjanssen: I've just sent the LayoutCombinator class, with PerWorkspace ported to it. 19:42:42 <arossato> dons: it is going to make everything A LOT safer 19:43:38 <sjanssen> arossato: I think the way forward is to push it into the mainline -- we can start collecting bug reports (if any exist) 19:43:49 <sjanssen> and it will prod me a bit more to take a closer look :) 19:43:58 <dons> its a good time to push too. 19:44:07 <dons> do it now, and we'll have 4-6 weeks to sort it all out. 19:45:15 <arossato> I'm going to push within a hour (after dinner) ... 20:00:51 <arossato> droundy: the LayoutCombinator class is quite an interesting beast... I was able to implement PerWorkspace in a few lines... to be explored, definitely! ... 20:04:41 <arossato> pushed! have a nice day!

On Fri, Feb 1, 2008 at 1:48 AM, Andrea Rossato < mailing_list@istitutocolli.org> wrote:
On Fri, Feb 01, 2008 at 12:22:32AM -0600, Spencer Janssen wrote:
As far as I know, there has only been one other proposal that solves the Xinerama issues with PerWorkspace -- adding a WorkspaceId argument to doLayout. I think we've all agreed that isn't so nice. My message proposal is actually very similar -- except that only layouts that care about workspace location need to handle these messages, whereas an extra argument to doLayout must be mentioned in every single layout instance.
Have you proposed another implementation that solves the Xinerama issue, and I missed it?
Yes you did. You actually did miss quite a lot of the stuff I've been sending recently. You are not the only one, though.
Hey, there's no need for that. You have been sending rather a lot of stuff lately, you know, you can't blame people for not quite being able to keep up. =)
As I say I did not propose to change doLayout, but just to change, in runLayout, doLayout with a doLayoutInWorkspace which takes the workspace and calls "doLayout (layout w)". The same for (emptyLayoutInWorkspace w = emptyLayout (layout w) and handleMessage.
Did you read this message and the attached patch? http://www.haskell.org/pipermail/xmonad/2008-January/004493.html
If a layout may be knowing the workspace it is running on, we could implement a general purpose combinator (my LayoutCombinator class and a general purpose CombinedLayout, implemented on top of the layout class.
Andrea, I would like to point out that having methods like doLayoutInWorkspace and so on have nothing to do with the viability of your LayoutCombinator class. These methods have only to do with implementing PerWorkspace in particular. In fact, I rather liked your LayoutCombinator class and would like a chance to try implementing PerWorkspace using it together with sjanssen's approach of special messages sent by a startup hook. I would like to ask if you can just re-push your LayoutCombinator class and CombinedLayout combinator, without making any changes to PerWorkspace? That way it will not break anything and we can play around with implementing things in terms of it.
As I mention here: http://code.google.com/p/xmonad/issues/detail?id=129 (I answered to your challenge, but you did not to mine!), with my proposal, PerWorkspace implementation would be:
instance LayoutCombinator PerWorkspace a where chooser (PerWorkspace wsIds) = do t <- getCurrentTag return $ if t `elem` wsIds then DoFirst else DoSecond
Again, you seem to be confusing the issue of the type of 'description' with the problem of getting PerWorkspace to work with xinerama. The above code still would not work with xinerama, which is my main goal. It also still does not work with messages that may be sent to a non-focused workspace. That implementation IS ACTUALLY working and has been in xmc repository
for a couple of days. Than I had to remove it since I asked for core support and I was told I would not get it.
No, it wasn't; there is still the issue of messages sent to non-focused workspaces, which probably wouldn't cause any problems most of the time (so it appeared to work) but could cause subtle bugs. I sent an explanation of this to the list earlier. Cheers, -Brent

On Fri, Feb 01, 2008 at 07:59:54AM -0500, Brent Yorgey wrote:
On Fri, Feb 1, 2008 at 1:48 AM, Andrea Rossato < mailing_list@istitutocolli.org> wrote:
Yes you did. You actually did miss quite a lot of the stuff I've been sending recently. You are not the only one, though.
Hey, there's no need for that. You have been sending rather a lot of stuff lately, you know, you can't blame people for not quite being able to keep up. =)
I did not intend to blame anyone for that, and if I gave that impression I really beg your pardon. I'm really tired and maybe I'm loosing the ability to calibrate my words, but I just wanted to say that, yes, I had sent a proposal for a xinerama safe implementation of PerWorkspace (not the details but the general ideas... the code is straight).
Andrea, I would like to point out that having methods like doLayoutInWorkspace and so on have nothing to do with the viability of your LayoutCombinator class. These methods have only to do with implementing PerWorkspace in particular. In fact, I rather liked your LayoutCombinator class and would like a chance to try implementing PerWorkspace using it together with sjanssen's approach of special messages sent by a startup hook. I would like to ask if you can just re-push your LayoutCombinator class and CombinedLayout combinator, without making any changes to PerWorkspace? That way it will not break anything and we can play around with implementing things in terms of it.
I didn't revert as a retaliation measure...;) It's a couple of days that I keep repeating that a LayoutCombinator class is broken due to the type signature of description, and I do not think is right to push in a public repository of an important collaborative project like ours code that I know is broken. Since I see this problem very clearly, I thought it should be evident to others too. It is not. So I decided to revert, and discuss we you, guys, about the issue: http://code.google.com/p/xmonad/issues/detail?id=129 When we reach an agreement on how to write that class correctly, we will push back. I was a bit harsh, I must confess that, because when I said that type signature was wrong I got answers as if I were a newbie who doesn't get the beauty of pureness. I was just talking about the beauty of pureness at a higher level of abstraction, in xmonad class system...;)
Again, you seem to be confusing the issue of the type of 'description' with the problem of getting PerWorkspace to work with xinerama. The above code still would not work with xinerama, which is my main goal. It also still does not work with messages that may be sent to a non-focused workspace.
No I do not. 1. xinerama issue -> doLayoutInWorkspace, emptyLayoutInWorkspace, handleMessageInWorkspace 2. LayoutCombinator class -> description type If I solve 2 and I get 1 the PerWorkspace implementation is 3 lines long. If I get 1 but I don't get 2 the implementation of PerWorkspace is longer but can be done. But in this case the LayoutCombinator class is bugged: either you confine it to pure combinators only (Choose, NewSelect and ToggleLayouts could be implemented, if I remember right), but PerWorkspace cannot be implememented.
No, it wasn't; there is still the issue of messages sent to non-focused workspaces, which probably wouldn't cause any problems most of the time (so it appeared to work) but could cause subtle bugs. I sent an explanation of this to the list earlier.
I hope what I said above clarifies my point. but you are right, in some of my messages I did some confusion on the two points (but believe me, the problem is quite clear to me). Hope this helps. Andrea

On Fri, Feb 01, 2008 at 07:59:54AM -0500, Brent Yorgey wrote:
On Fri, Feb 1, 2008 at 1:48 AM, Andrea Rossato < mailing_list@istitutocolli.org> wrote: That implementation IS ACTUALLY working and has been in xmc repository
No, it wasn't; there is still the issue of messages sent to non-focused workspaces, which probably wouldn't cause any problems most of the time (so it appeared to work) but could cause subtle bugs. I sent an explanation of this to the list earlier.
I think you may understand that by "working" I mean conceptually sounded and actually implementable. That specific implementation was not working in the way it should because, I've been arguing, it exposed the lack of composability and the lack of expressiveness of the LayoutClass, due to the methods' types that were chosen. I would like to stress the relationship between a method's type and the expressiveness of a class. As I pointed out in my "adventures in types", David provided us with a great tool when he hacked the modifier class. Still that class was not expressive enough to implement AvoidStruts (from ManageDocks), because modifyLayout was not provided. And so, at that time, you should implement AvoidStruct as a layout combinator. I believe my implementation is cleaner, because now you can *change* the layout class and all you need to do it's just to port the modifier class. The very same applies the Named. And did you see how many locs there are in Named now? Why do I care about PerWorkspace so much that I'm buzzing everyone about it? Because when I saw it I thought - and still think - that it was a great hack, that showed my how much you can do with the type system. Do you remember when David told you to just push the list in the type? I'm just applying that principle on a regular basis, now. Thanks to you and David... shouldn't we agree? ;) Cheers, Andrea

On Thu, Jan 31, 2008 at 2:42 PM, Spencer Janssen
On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much.
\begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code}
'selected' is Nothing until we either figure out which workspace the layout is on, or we're forced to render before we figure it out. 'choices' maps workspaceids to desired layouts. 'default' is used when the WorkspaceId isn't in our 'choices' map, or we're forced to render before we know which workspace
we're on.
This is similar to what I had before, except I very much like the idea of storing a "Maybe Layout" instead of just a "Maybe Bool". Much less of a headache. =)
Now, the million dollar question: how do we figure out which workspace a layout is on?
\begin{code} data YouAreHere = YAH WorkspaceId deriving Typeable instance Message YouAreHere \end{code}
Ah, excellent! I hadn't thought of the idea of a special message.
Now we just need to arrange for this message to be sent. I see two options:
- add a 'startupHook :: X ()' that is executed when xmonad starts. This might be useful for other applications too. A minor issue is that the user will have to edit startupHook and layoutHook to use PerWorkspace successfully.
This option makes more sense to me. In fact, the other day someone was asking about the possibility of just such a hook; I played around with it for a bit but wasn't sure of the best place to add a call to it in the core. Would it really be possible to implement a function to correctly send all the YouAreHere messages, with no other support from the core than just calling the startupHook? I'll have to look into it. If so this seems the way to go.
- have the core send YouAreHere messages to each visible workspace during each refresh. This is easier for the user, but it requires adding more to the core.
This sounds sort of ugly to me. Again, it's the principle of making a bunch of very specific changes to the core which have not much purpose other than to support a single extension. -Brent

On Thu, Jan 31, 2008 at 2:42 PM, Spencer Janssen
On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much.
\begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code}
So, I took a crack at implementing (something like) this today. The problem I ran into is that (Layout a) is not an instance of Read, so PerWorkspace cannot derive Read either. Is there any way around this? Or do I have to go back to caching a (Maybe Bool) and using that to decide on which of two layouts to use, instead of directly caching a (Maybe (Layout a))? Ideas? -Brent

Excerpts from Brent Yorgey's message of Fri Feb 01 22:53:20 +0100 2008:
On Thu, Jan 31, 2008 at 2:42 PM, Spencer Janssen
wrote: On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much.
\begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code}
So, I took a crack at implementing (something like) this today. The problem I ran into is that (Layout a) is not an instance of Read, so PerWorkspace cannot derive Read either. Is there any way around this? Or do I have to go back to caching a (Maybe Bool) and using that to decide on which of two layouts to use, instead of directly caching a (Maybe (Layout a))?
Ideas?
What about "instance Read a => Read (Layout a)"? -- Nicolas Pouillard aka Ertai

On Fri, Feb 1, 2008 at 5:04 PM, Nicolas Pouillard < nicolas.pouillard@gmail.com> wrote:
On Thu, Jan 31, 2008 at 2:42 PM, Spencer Janssen
wrote: On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much.
\begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code}
So, I took a crack at implementing (something like) this today. The
Excerpts from Brent Yorgey's message of Fri Feb 01 22:53:20 +0100 2008: problem
I ran into is that (Layout a) is not an instance of Read, so PerWorkspace cannot derive Read either. Is there any way around this? Or do I have to go back to caching a (Maybe Bool) and using that to decide on which of two layouts to use, instead of directly caching a (Maybe (Layout a))?
Ideas?
What about "instance Read a => Read (Layout a)"?
Well, since Layout is an existential wrapper, that's not possible -- it hides the type of the wrapped layout. I know that lots of work has already gone into the xmonad core getting around this issue. =) Hmm, just thinking out loud here... note that I don't actually care about being able to read the (Layout a) value back in, since after serialization/restart the startupHook will get run again anyway, and the correct workspace will get re-cached. So perhaps I can just write my own explicit Read instance for PerWorkspace that somehow ignores that element and just initializes the read value to Nothing. Sounds scary. =) -Brent

Excerpts from Brent Yorgey's message of Fri Feb 01 23:08:30 +0100 2008:
On Fri, Feb 1, 2008 at 5:04 PM, Nicolas Pouillard < nicolas.pouillard@gmail.com> wrote:
On Thu, Jan 31, 2008 at 2:42 PM, Spencer Janssen
wrote: On Wed, Jan 30, 2008 at 07:29:58PM -0500, Brent Yorgey wrote:
1. PerWorkspace is an inelegant hack with several icky problems:
Agreed. It is approaching the limits of xmonad's layout design. However, I think we can accomplish PerWorkspace behavior without changing too much.
\begin{code} data PerWS = PerWS { selected :: Maybe Layout , choices :: Map WorkspaceId Layout , default :: Layout } \end{code}
So, I took a crack at implementing (something like) this today. The
Excerpts from Brent Yorgey's message of Fri Feb 01 22:53:20 +0100 2008: problem
I ran into is that (Layout a) is not an instance of Read, so PerWorkspace cannot derive Read either. Is there any way around this? Or do I have to go back to caching a (Maybe Bool) and using that to decide on which of two layouts to use, instead of directly caching a (Maybe (Layout a))?
Ideas?
What about "instance Read a => Read (Layout a)"?
Well, since Layout is an existential wrapper, that's not possible -- it hides the type of the wrapped layout. I know that lots of work has already gone into the xmonad core getting around this issue. =)
Yes, I didn't understand why this line compile and seems to solve the problem. Indeed I've encountered this same issue while doing another xmonad extension. -- Nicolas Pouillard aka Ertai
participants (6)
-
Andrea Rossato
-
Brent Yorgey
-
David Roundy
-
Nicolas Pouillard
-
Spencer Janssen
-
Valery V. Vorotyntsev