
The current floating layer code handles the interface to the outside world quite nicely, but interacts strangely with fullscreen mode. The problems stem from the fact that windows are lifted into the floating layer by setting a bit flag, basically. They are then rendered separately if this flag is set. This is good, but means that floating windows keep an implicit position in the tiled ordering -- although they don't physically appear to be in the tiled layer. This leads to some oddities: * moving a floating window in fullscreen tiled mode, will shift focus of the tiled layer to the window after the implicit position of the floating mode. * mod-shift-j reorders the implicit position of a floating window in the tiled layer, but this change isn't visible I think the best way to solve this is to move from an 'implicit' floating layer, denoted by flag bits, to an explicit floating layer on each workspace: data Workspace i a = Workspace { tag :: !i , tiled :: Stack a , float :: Stack a } Now we can be sure that the floating layer is fully detached, and can be operated on in isolation, as its own zipper. For one, this will mean fullscreen mode works (since focus isn't lost on the tiled stack). Should be able to reuse the existing code (changing modify a bit). We also get a new set of operatoins on the float layer alone, or on the union of the two layers. Spencer, Jason, suggestions? Everyone else, not tracking the stable branch -- what do you think of the tiling mode as it is? this will likely be the main new (and final!) feature missing before 0.3 (and forward to 1.0). -- Don

On Thu, May 31, 2007 at 07:17:09PM +1000, Donald Bruce Stewart wrote:
The current floating layer code handles the interface to the outside world quite nicely, but interacts strangely with fullscreen mode. The problems stem from the fact that windows are lifted into the floating layer by setting a bit flag, basically. They are then rendered separately if this flag is set.
This is good, but means that floating windows keep an implicit position in the tiled ordering -- although they don't physically appear to be in the tiled layer.
This leads to some oddities: * moving a floating window in fullscreen tiled mode, will shift focus of the tiled layer to the window after the implicit position of the floating mode. * mod-shift-j reorders the implicit position of a floating window in the tiled layer, but this change isn't visible
I think the best way to solve this is to move from an 'implicit' floating layer, denoted by flag bits, to an explicit floating layer on each workspace:
I agree. I can imagine workarounds for some of those problems, but not for the most glaring issue, which is that floating breaks layouts which depend upon focus.
data Workspace i a = Workspace { tag :: !i , tiled :: Stack a , float :: Stack a }
With that, you know which window has the focus in each layer, but how would you know which layer has focus? Also, you need to store the RationalRect with their x/y/w/h information somewhere. Are you thinking of retaining the "floating" map? Or float :: Stack (a, RationalRect)? Jason Creighton

On Thu, May 31, 2007 at 05:59:05PM -0600, Jason Creighton wrote:
On Thu, May 31, 2007 at 07:17:09PM +1000, Donald Bruce Stewart wrote:
data Workspace i a = Workspace { tag :: !i , tiled :: Stack a , float :: Stack a }
With that, you know which window has the focus in each layer, but how would you know which layer has focus? Also, you need to store the RationalRect with their x/y/w/h information somewhere. Are you thinking of retaining the "floating" map? Or float :: Stack (a, RationalRect)?
What about something like: data Workspace i a = Parent { tag :: !i , child :: Stack (Workspace a) } | Workspace { tag :: !i , thewindows :: Stack a } Then we can put two or more workspaces together, and the same set of functions can be used to track focus, etc. This would naturally allow for multiple sets of floating windows (sticky, etc). Maybe it's overkill, but when I see the same problem come up again and again (screens each have a single workspace focussed, "tiled" has a single window focussed, "float" has a single window focussed, workspaces each have one of "tile" or "float" subworkspace focussed, I think that reuse of code sounds like a good plan. Or maybe, if we didn't want arbitrary nesting, we'd want "what's visible on a given screen" to be of type data ScreenContents i a = ScreenContents { tag :: !i , thechildren :: Stack (Workspace a) } data Workspace i a = Workspace { tag :: !i , thewindows :: Stack a } We'd reuse the same focus code we've already got. Either way (my approach or dons' suggestion) we have to decide on how to deal with things like window focus cycling (does it cycle through float and tiled windows separately?) But my suggestion could lead to (I think) a more natural replacement for the docking work, for example. A dock could be just another Workspace, which might be visible on many or all of your ScreenContents'. I can't see to the end of this idea, how it'd all work, but it seems like the elegant direction to move. Of course, one would want to move gradually. On the other hand, if dons (or someone else) came up with a way to represent the nested workspace as a tree-like zipper, maybe everything would suddenly become simpler. This sounds a lot like the zipper idea coming back at us. -- David Roundy Department of Physics Oregon State University

droundy:
On Thu, May 31, 2007 at 05:59:05PM -0600, Jason Creighton wrote:
On Thu, May 31, 2007 at 07:17:09PM +1000, Donald Bruce Stewart wrote:
data Workspace i a = Workspace { tag :: !i , tiled :: Stack a , float :: Stack a }
With that, you know which window has the focus in each layer, but how would you know which layer has focus? Also, you need to store the RationalRect with their x/y/w/h information somewhere. Are you thinking of retaining the "floating" map? Or float :: Stack (a, RationalRect)?
What about something like:
data Workspace i a = Parent { tag :: !i , child :: Stack (Workspace a) } | Workspace { tag :: !i , thewindows :: Stack a }
Then we can put two or more workspaces together, and the same set of functions can be used to track focus, etc. This would naturally allow for multiple sets of floating windows (sticky, etc). Maybe it's overkill, but when I see the same problem come up again and again (screens each have a single workspace focussed, "tiled" has a single window focussed, "float" has a single window focussed, workspaces each have one of "tile" or "float" subworkspace focussed, I think that reuse of code sounds like a good plan.
Or maybe, if we didn't want arbitrary nesting, we'd want "what's visible on a given screen" to be of type
data ScreenContents i a = ScreenContents { tag :: !i , thechildren :: Stack (Workspace a) } data Workspace i a = Workspace { tag :: !i , thewindows :: Stack a }
We'd reuse the same focus code we've already got. Either way (my approach or dons' suggestion) we have to decide on how to deal with things like window focus cycling (does it cycle through float and tiled windows separately?) But my suggestion could lead to (I think) a more natural replacement for the docking work, for example. A dock could be just another Workspace, which might be visible on many or all of your ScreenContents'.
I can't see to the end of this idea, how it'd all work, but it seems like the elegant direction to move. Of course, one would want to move gradually. On the other hand, if dons (or someone else) came up with a way to represent the nested workspace as a tree-like zipper, maybe everything would suddenly become simpler. This sounds a lot like the zipper idea coming back at us.
Yes, the more I ponder it, the more two layers really appears to act like a 2 level tree zipper. Focus is the current node, in the current layer, on the current workspace. The new idea is the layer separating floating and tiled windows. Some ops would traverse both. i'll think more about this tonight. If we find the right data structure, the code, and the right UI, will follow. -- Don (practicing zen in the art of coding)
participants (3)
-
David Roundy
-
dons@cse.unsw.edu.au
-
Jason Creighton