Tabbed.addTabs broken?

I'm writing here instead of asking over IRC because it's a bit long
and I don't want to generate confusion (I'm quite too good at
that...;)
There are 2 patches I don't understand.
This one breaks Tabbed.addTabs:
Tue Feb 5 21:23:43 CET 2008 David Roundy

I will repeat that the correct way to designate decoration windows is to attach a decoration property to them, both to answer questions of "is this a real window?" and to be able to recover if xmonad exits unexpectedly leaving its decoration windows around (otherwise restarting xmonad turns decoration windows into managed windows because it doesn't know any better). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Mon, Feb 11, 2008 at 02:20:46PM -0500, Brandon S. Allbery KF8NH wrote:
I will repeat that the correct way to designate decoration windows is to attach a decoration property to them, both to answer questions of "is this a real window?" and to be able to recover if xmonad exits unexpectedly leaving its decoration windows around (otherwise restarting xmonad turns decoration windows into managed windows because it doesn't know any better).
decoration windows have the override_redirect bit set to true, and so xmonad is not going to manage them on a restart. a property could be a cleaner solution but I'm not so sure. Thanks, Andrea

On Feb 11, 2008, at 14:31 , Andrea Rossato wrote:
On Mon, Feb 11, 2008 at 02:20:46PM -0500, Brandon S. Allbery KF8NH wrote:
I will repeat that the correct way to designate decoration windows is to attach a decoration property to them, both to answer questions of "is this a real window?" and to be able to recover if xmonad exits unexpectedly leaving its decoration windows around (otherwise restarting xmonad turns decoration windows into managed windows because it doesn't know any better).
decoration windows have the override_redirect bit set to true, and so xmonad is not going to manage them on a restart.
So instead they just hang around forever. You still want the property in that case, so a restarted xmonad can correctly recognize them as orphaned and destroy them. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Mon, Feb 11, 2008 at 02:36:27PM -0500, Brandon S. Allbery KF8NH wrote:
On Feb 11, 2008, at 14:31 , Andrea Rossato wrote:
On Mon, Feb 11, 2008 at 02:20:46PM -0500, Brandon S. Allbery KF8NH wrote:
I will repeat that the correct way to designate decoration windows is to attach a decoration property to them, both to answer questions of "is this a real window?" and to be able to recover if xmonad exits unexpectedly leaving its decoration windows around (otherwise restarting xmonad turns decoration windows into managed windows because it doesn't know any better).
decoration windows have the override_redirect bit set to true, and so xmonad is not going to manage them on a restart.
So instead they just hang around forever. You still want the property in that case, so a restarted xmonad can correctly recognize them as orphaned and destroy them.
Won't the X server clean them up when the client that created them exits? (the Display file descriptor is set to close on exec, as far as I know) Cheers, Spencer Janssen

On Feb 12, 2008, at 5:02 , Spencer Janssen wrote:
Won't the X server clean them up when the client that created them exits? (the Display file descriptor is set to close on exec, as far as I know)
Hm, right, for some reason I was thinking window managers get privileged behavior (it is certainly possible for windows to outlive their creators, windows and pixmaps are actually shared resources as far as the server is concerned, pixmap leaks are far from unknown, window leaks rarely occur but have been seen occasionally). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Tue, Feb 12, 2008 at 09:29:16AM -0500, Brandon S. Allbery KF8NH wrote:
On Feb 12, 2008, at 5:02 , Spencer Janssen wrote:
Won't the X server clean them up when the client that created them exits? (the Display file descriptor is set to close on exec, as far as I know)
Hm, right, for some reason I was thinking window managers get privileged behavior (it is certainly possible for windows to outlive their creators, windows and pixmaps are actually shared resources as far as the server is concerned, pixmap leaks are far from unknown, window leaks rarely occur but have been seen occasionally).
The privledged behavior comes from a special 'close-down mode flag', which I'm pretty sure xmonad doesn't use. (and the design of X means that it isn't really sensical to distinguish window managers) Stefan

On Mon, Feb 11, 2008 at 05:01:40PM +0100, Andrea Rossato wrote:
There are 2 patches I don't understand.
This one breaks Tabbed.addTabs:
How does it do so? What happens that is wrong?
Tue Feb 5 21:23:43 CET 2008 David Roundy
* make tabbed work nicely with LayoutCombinators and WindowNavigation. The problem is that WindowNavigation assumes all windows are navigable, and it was getting confused by decorations. With a bit of work, we can decorate windows *after* combining layouts just fine. since Tabbed now assumes that the windows to be decorated are only those with the same rectangle: wrs' = filter ((==r) . snd) wrs
Which is fine only with Simplest. If you use it with some other layout (which does not give the same rectangle to all windows) then this will always hold: if length wrs' <= 1 then Nothing
I'm not clear what the problem is here. The theory of addTabbed was that the tabbed decoration should be able to decorate a "mixed" layout, in which some of the windows are supposed to be tabbed, and others are not (and those don't get decorated). If it doesn't do this, then yes, it's broken.
It also assumes the decoration to have the same y coordinate of the window to be decorated - the window must be shrunk. That is to say, if we were to remove the first constraint, we would end up with a SimpleDecoration layout modifier. :)
I'm a little unclear here: what is it that you want tabbed to do? I had to make this change (I think) in order to make tabbed work properly when it is placed in a subset of the screen. Your tabbed was trying to draw the tabs at the top of the screen regardless, as I recall. Certainly we must use the locations of the windows to determine the locations of the tabs, otherwise everythings going to look crazy.
But, as far as I understand, this is needed for WindowNavigation (I do not understand well its code, and I didn't have time to study it).
No, this bit is no longer needed for WindowNavigation. It is, however, needed if you want to apply this decoration to a more interesting layout than Simplest. (Which was required by WindowNavigation, prior to the patch mentioned below.) I do think this is a good idea, as it gives us a more composable interface (i.e. we could combine layouts *prior* to adding decorations, which might have advantages).
Which brings me to this patch:
Tue Feb 5 21:35:56 CET 2008 David Roundy
* make WindowNavigation ignore decorations. where you check the stack to see if a window is a decoration.
There is also another way to check if a window is a decoration, by checking its attributes (isDecoration :: Window -> X Bool does this).
I think this patch does things the right way. Why use isDecoration when we can just check whether the windows are present in the stack? By definition, the windows we want to focus are those which are in the stack. i.e. it's not necessarily just decorations we want to filter out, but specifically any windows that aren't part of the stack. It's better *not* to use isDecoration, on the principle that we should be checking for the actual property that we require (presense in the stack), not for a different property that happens to be true for the same windows.
I'm writing because I wonder if we can remove that constrain from Tabbed and solve the WindowNavigation problem in another way.
Which constraint was this in Tabbed? The one that requires it to only display visible windows? On slower computers (e.g. my laptop) it is very important to actually hide hidden windows, which is quite unrelated to WindowNavigation, simply to the fact that it's very hard to use the window manager when the screen keeps flashing between different windows when I change focus. I haven't upgraded my xmonad since I wrote these patches, and doubt I'll upgrade any time soon (there's always the possibility when upgrading that I'll lose a half-day of work getting thing going again like they were before...), but my feeling is that tabbed and WindowNavigation aren't very broken (unless they've gotten more broken). -- David Roundy Department of Physics Oregon State University

On Tue, Feb 12, 2008 at 06:17:55PM -0500, David Roundy wrote:
This one breaks Tabbed.addTabs:
How does it do so? What happens that is wrong?
My use of the word "broken" is confusing. Sorry for that. Nothing wrong is happening. What I meant is that addTabs is going to work *only* with Simplest at the present time, because Simplest is the only one in which 2 windows may be stacked.
Tue Feb 5 21:23:43 CET 2008 David Roundy
* make tabbed work nicely with LayoutCombinators and WindowNavigation. The problem is that WindowNavigation assumes all windows are navigable, and it was getting confused by decorations. With a bit of work, we can decorate windows *after* combining layouts just fine. I'm not clear what the problem is here. The theory of addTabbed was that the tabbed decoration should be able to decorate a "mixed" layout, in which some of the windows are supposed to be tabbed, and others are not (and those don't get decorated). If it doesn't do this, then yes, it's broken.
It does so, and so it is not broken. My fault, since I thought it was just more general, and could be used for, say, Circle, or Mirror tiled. At first Layout.Tabbed.hs was exporting a style that could be used with any layout, not just with layouts with stacked windows.
It also assumes the decoration to have the same y coordinate of the window to be decorated - the window must be shrunk. That is to say, if we were to remove the first constraint, we would end up with a SimpleDecoration layout modifier. :)
I'm a little unclear here: what is it that you want tabbed to do? I had to make this change (I think) in order to make tabbed work properly when it is placed in a subset of the screen. Your tabbed was trying to draw the tabs at the top of the screen regardless, as I recall. Certainly we must use the locations of the windows to determine the locations of the tabs, otherwise everythings going to look crazy.
Now I think I get exactly the problem your patch was trying to solve. What I want is to have a tabbed-like (let's call it this way) that can be used with any layout. For instance, a tabbed-like decoration that works with a floating layout: http://code.haskell.org/~arossato/xmonadShots/floatSimpleTabbed.png (Actually I'm not using such a layout, but I had a request for something like this). What I was asking was that: 1. can I change Layout.Tabbed.TabbedDecoration so that something like this can be done with that style without breaking WindowNavigation - and possibly other things? If yes, do I need to change WidowNavigation? If this is another yes, how? 2. Suppose that Layout.Tabbed.TabbedDecoration is not to be changed (because we need a style like that in order to get a properly working (real) tabbed layout). Now, if I write a TabbedLikeDecoration style, which will place decorations on the top of the screen, is that going to break WindowNavigation? May I change WindowNavigation to allow such a style to be used with it? (Note that I followed option 2. for DecorationMadness, but without exporting this TabbedLikeDecoration style).
But, as far as I understand, this is needed for WindowNavigation (I do not understand well its code, and I didn't have time to study it).
No, this bit is no longer needed for WindowNavigation. It is, however, needed if you want to apply this decoration to a more interesting layout than Simplest. (Which was required by WindowNavigation, prior to the patch mentioned below.) I do think this is a good idea, as it gives us a more composable interface (i.e. we could combine layouts *prior* to adding decorations, which might have advantages).
This means that both option 1 and option 2 would work fine with WindowNavigation, without any change?
It's better *not* to use isDecoration, on the principle that we should be checking for the actual property that we require (presense in the stack), not for a different property that happens to be true for the same windows.
This is an interesting point. Probably I should just change isDecoration to use the stack, right?
I haven't upgraded my xmonad since I wrote these patches, and doubt I'll upgrade any time soon (there's always the possibility when upgrading that I'll lose a half-day of work getting thing going again like they were before...), but my feeling is that tabbed and WindowNavigation aren't very broken (unless they've gotten more broken).
I hope I clarified that both tabbed and WindowNavigation are *not* broken. But I don't want to break them with the style I need (the TabbedLikeDecoration style) Thanks for you help. Andrea

On Wed, Feb 13, 2008 at 10:34:24AM +0100, Andrea Rossato wrote:
On Tue, Feb 12, 2008 at 06:17:55PM -0500, David Roundy wrote:
Tue Feb 5 21:23:43 CET 2008 David Roundy
* make tabbed work nicely with LayoutCombinators and WindowNavigation. The problem is that WindowNavigation assumes all windows are navigable, and it was getting confused by decorations. With a bit of work, we can decorate windows *after* combining layouts just fine. I'm not clear what the problem is here. The theory of addTabbed was that the tabbed decoration should be able to decorate a "mixed" layout, in which some of the windows are supposed to be tabbed, and others are not (and those don't get decorated). If it doesn't do this, then yes, it's broken.
It does so, and so it is not broken. My fault, since I thought it was just more general, and could be used for, say, Circle, or Mirror tiled.
At first Layout.Tabbed.hs was exporting a style that could be used with any layout, not just with layouts with stacked windows.
It also assumes the decoration to have the same y coordinate of the window to be decorated - the window must be shrunk. That is to say, if we were to remove the first constraint, we would end up with a SimpleDecoration layout modifier. :)
I'm a little unclear here: what is it that you want tabbed to do? I had to make this change (I think) in order to make tabbed work properly when it is placed in a subset of the screen. Your tabbed was trying to draw the tabs at the top of the screen regardless, as I recall. Certainly we must use the locations of the windows to determine the locations of the tabs, otherwise everythings going to look crazy.
Now I think I get exactly the problem your patch was trying to solve. What I want is to have a tabbed-like (let's call it this way) that can be used with any layout.
For instance, a tabbed-like decoration that works with a floating layout: http://code.haskell.org/~arossato/xmonadShots/floatSimpleTabbed.png
I actually realized this yesterday when I saw your http://code.haskell.org/~arossato/xmonadShots/circleSimpleTabbed.png and realized that this could be useful. It's also (as you say, and I was thinking to write to you) a tabbed-like decoration, rather than a "true tabbed" decoration, which is different--but both potentially useful. Your "tabbed-like" decoration actually serves the function of a gnome-like bar, which lists windows present and allows you to give them focus. As opposed to the "true-tabbed" behavior which serves the same function served by e.g. firefox tabs, allowing one to combine several windows together to reduce clutter while still maintaining ready accessibility of the hidden windows. (I'm sure you understand this, but figure it's best to be clear when possible, since we so recently had different pictures of what addTabs ought to do...) I can't help but wonder if a tabbed-like interface is best acheived by supporting EWMH or something, so gnome-panel or kicker could serve this function. But there's no harm in having redundant means of acheiving the same functionality.
(Actually I'm not using such a layout, but I had a request for something like this).
What I was asking was that:
1. can I change Layout.Tabbed.TabbedDecoration so that something like this can be done with that style without breaking WindowNavigation - and possibly other things? If yes, do I need to change WidowNavigation? If this is another yes, how?
No, you shouldn't need to do anything with WindowNavigation to implement tabbed-like decorations. I presume you're thinking to have related modifiers, one for "true-tabbed" and one for "tabbed-like" decorating? That sounds like a good idea to me.
But, as far as I understand, this is needed for WindowNavigation (I do not understand well its code, and I didn't have time to study it).
No, this bit is no longer needed for WindowNavigation. It is, however, needed if you want to apply this decoration to a more interesting layout than Simplest. (Which was required by WindowNavigation, prior to the patch mentioned below.) I do think this is a good idea, as it gives us a more composable interface (i.e. we could combine layouts *prior* to adding decorations, which might have advantages).
This means that both option 1 and option 2 would work fine with WindowNavigation, without any change?
Right.
It's better *not* to use isDecoration, on the principle that we should be checking for the actual property that we require (presense in the stack), not for a different property that happens to be true for the same windows.
This is an interesting point. Probably I should just change isDecoration to use the stack, right?
Yeah, that sounds reasonable, depending on what you plan to use isDecoration for. If you plan to do anything "special" with decoration windows (that you wouldn't want to have affect other xmonad-created windows), then you'd still want some way to distinguish. e.g. if we had a modular prompt code, that'd create a window, which might not be considered a "decoration". -- David Roundy Department of Physics Oregon State University

On Wed, Feb 13, 2008 at 10:10:19AM -0500, David Roundy wrote:
I can't help but wonder if a tabbed-like interface is best acheived by supporting EWMH or something, so gnome-panel or kicker could serve this function. But there's no harm in having redundant means of acheiving the same functionality.
I stopped thinking that reimplementing one of gnome-pannel functionality may be deemed as redundant. At least after the day when I had to set up a cron job to kill gnome-pannel every night, since it (or some of its applets) was leaking so much memory that in the morning my laptop was barely usable...;) Just kidding, obviously. BTW, that was a feature request, and it was that feature request that got me started with the new decoration code. It all started with the idea to make Tabbed a layout modifier (that is to say, and instance of the LayoutModifier class).
No, you shouldn't need to do anything with WindowNavigation to implement tabbed-like decorations. I presume you're thinking to have related modifiers, one for "true-tabbed" and one for "tabbed-like" decorating? That sounds like a good idea to me.
Yes, this is my idea.
It's better *not* to use isDecoration, on the principle that we should be checking for the actual property that we require (presense in the stack), not for a different property that happens to be true for the same windows.
This is an interesting point. Probably I should just change isDecoration to use the stack, right?
Yeah, that sounds reasonable, depending on what you plan to use isDecoration for. If you plan to do anything "special" with decoration windows (that you wouldn't want to have affect other xmonad-created windows), then you'd still want some way to distinguish. e.g. if we had a modular prompt code, that'd create a window, which might not be considered a "decoration".
Actually I don't have any specific plan. I wrote isDecoration when I fixed (your) LayoutHints - which was applying hints to decorations too. I thought a function to discriminate between decoration and managed windows should be needed. This is the reason why I asked why you didn't use it. And your answer makes me think we should get rid of it and write something like: isInStack :: Stack a -> Window -> Bool Cheers, Andrea

I also have some more general thoughts your mail generated. On Tue, Feb 12, 2008 at 06:17:55PM -0500, David Roundy wrote:
I'm a little unclear here: what is it that you want tabbed to do? I had to make this change (I think) in order to make tabbed work properly when it is placed in a subset of the screen. Your tabbed was trying to draw the tabs at the top of the screen regardless, as I recall. Certainly we must use the locations of the windows to determine the locations of the tabs, otherwise everythings going to look crazy.
There are cases in which the window's location cannot be used, such as the case of a floating layout with a tabbed-like decoration. I think that in such cases we must use the screen rectangle a layout (or a layout modifier) gets in doLayout/redoLayout. LayoutModifier has the modifyLayout method for this purpose only: change the rectangle (or the stack, which is quite uncommon - no one is doing so right now) and produce the (window,rectangle) list accordingly. But probably this is incompatible with what comes next.
But, as far as I understand, this is needed for WindowNavigation (I do not understand well its code, and I didn't have time to study it).
No, this bit is no longer needed for WindowNavigation. It is, however, needed if you want to apply this decoration to a more interesting layout than Simplest. (Which was required by WindowNavigation, prior to the patch mentioned below.) I do think this is a good idea, as it gives us a more composable interface (i.e. we could combine layouts *prior* to adding decorations, which might have advantages).
Applying decorations after combining layouts is definitely something *very* good. I'm wondering if this is compatible with the above. (Probably not?) (And so, this would answer also my previous mail, probably: a TabbedLikeDecoration style is *incompatible* with the possibility of decorating layouts after combining them). What I'm asking is this: if there is this incompatibility, should we enforce it in the DecorationStyle class (which would mean, remove the screen rectangle from the decorate method) or just warn the user that a given style cannot be used for combined layouts? Thanks for you kind attention. Andrea

On Wed, Feb 13, 2008 at 11:12:34AM +0100, Andrea Rossato wrote:
I also have some more general thoughts your mail generated.
On Tue, Feb 12, 2008 at 06:17:55PM -0500, David Roundy wrote:
I'm a little unclear here: what is it that you want tabbed to do? I had to make this change (I think) in order to make tabbed work properly when it is placed in a subset of the screen. Your tabbed was trying to draw the tabs at the top of the screen regardless, as I recall. Certainly we must use the locations of the windows to determine the locations of the tabs, otherwise everythings going to look crazy.
There are cases in which the window's location cannot be used, such as the case of a floating layout with a tabbed-like decoration. I think that in such cases we must use the screen rectangle a layout (or a layout modifier) gets in doLayout/redoLayout.
Why not use the input-rectangle that's given to doLayout? i.e. what if I want to do something like this (fooLayout *|* tabbedLikeDecoration floatingLayout) In this case I'd want the tabbedLikeDecoration to place its tabs on the right hand side of the screen, on the principle that layout combinators ought to work such that each layout only decorates in its part of the screen. In contrast, I'd expect: (tabbedLikeDecoration (fooLayout *|* floatingLayout)) to produce tabs covering the entire screen (and have tabs for all the windows, not just the floatingLayout ones). And I'd expect (tabbedLikeDecoration fooLayout *|* tabbedLikeDecoration floatingLayout) to produce tabs on the left-hand side for the windows on the left, and tabs on the right for the windows on the right.
LayoutModifier has the modifyLayout method for this purpose only: change the rectangle (or the stack, which is quite uncommon - no one is doing so right now) and produce the (window,rectangle) list accordingly.
But probably this is incompatible with what comes next.
But, as far as I understand, this is needed for WindowNavigation (I do not understand well its code, and I didn't have time to study it).
No, this bit is no longer needed for WindowNavigation. It is, however, needed if you want to apply this decoration to a more interesting layout than Simplest. (Which was required by WindowNavigation, prior to the patch mentioned below.) I do think this is a good idea, as it gives us a more composable interface (i.e. we could combine layouts *prior* to adding decorations, which might have advantages).
Applying decorations after combining layouts is definitely something *very* good. I'm wondering if this is compatible with the above. (Probably not?)
I think this is compatible with a tabbedLikeDecoration that obeys its input rectangle (which ought to have a decent name, but I can't think of one at the moment), as described above.
(And so, this would answer also my previous mail, probably: a TabbedLikeDecoration style is *incompatible* with the possibility of decorating layouts after combining them).
I don't think it's incompatible with combinators, as described above. Of course, you could get very weird effects if you did something like tabbedLikeDecoration (tabbedLikeDecoration fooLayout *|* tabbedLikeDecoration floatingLayout) -- David Roundy Department of Physics Oregon State University

On Wed, Feb 13, 2008 at 10:45:49AM -0500, David Roundy wrote:
Why not use the input-rectangle that's given to doLayout? i.e. what if I want to do something like this
'decorate' and 'pureDecoration' are using precisely that rectangle (the one passed to 'redoLayout', which is the one passed to 'doLayout').
(fooLayout *|* tabbedLikeDecoration floatingLayout) (tabbedLikeDecoration (fooLayout *|* floatingLayout)) (tabbedLikeDecoration fooLayout *|* tabbedLikeDecoration floatingLayout)
the fact that this is not happening with my previous TabbedDecoration is a bug I was not aware of. Now I can indeed see it and I want it to be fixed (which still doesn't mean that we will have just one TabbedDecoration for real tabbed layouts and for tabbed-like decorations, obviously).
Applying decorations after combining layouts is definitely something *very* good. I'm wondering if this is compatible with the above. (Probably not?)
I think this is compatible with a tabbedLikeDecoration that obeys its input rectangle (which ought to have a decent name, but I can't think of one at the moment), as described above.
The fact that it does not is puzzling, as I said. I need to have a closer look.
I don't think it's incompatible with combinators, as described above. Of course, you could get very weird effects if you did something like
tabbedLikeDecoration (tabbedLikeDecoration fooLayout *|* tabbedLikeDecoration floatingLayout)
I have a patch that at least will prevent Decoration from decorating decorations, but before pushing I want to rewrite isDecoration... ;) Andrea
participants (5)
-
Andrea Rossato
-
Brandon S. Allbery KF8NH
-
David Roundy
-
Spencer Janssen
-
Stefan O'Rear