darcs patch: new contrib module, Layout.PerWorkspace

As seen on xmonad@! A module which allows you to configure layouts
per-workspace. Testing, comments, criticisms, edits, etc. welcome.
Mon Nov 19 21:46:12 EST 2007 Brent Yorgey

On Mon, Nov 19, 2007 at 09:54:06PM -0500, Brent Yorgey wrote:
As seen on xmonad@! A module which allows you to configure layouts per-workspace. Testing, comments, criticisms, edits, etc. welcome.
Mon Nov 19 21:46:12 EST 2007 Brent Yorgey
* new contrib module: Layout.PerWorkspace This module allows you to configure layouts on a per-workspace basis, rather than specifying the same layout for all workspaces. (Of course, you still really *are* specifying the same layout for all workspaces, it just acts differently depending on the workspace. =)
Applied. Cool beans!

On Mon, Nov 19, 2007 at 09:54:06PM -0500, Brent Yorgey wrote:
As seen on xmonad@! A module which allows you to configure layouts per-workspace. Testing, comments, criticisms, edits, etc. welcome.
This is buggy when multiple screens are in use, because of the following code: -- figure out which layout to use based on the current workspace. doLayout (PerWorkspace wsId Nothing l1 l2) r s = do t <- getCurrentTag doLayout (PerWorkspace wsId (Just $ wsId == t) l1 l2) r s There's no guarantee that the *current* screen is the one that's having doLayout called. :( We also have trouble with: handleMessage (PerWorkspace wsId Nothing l1 l2) m = do t <- getCurrentTag handleMessage (PerWorkspace wsId (Just $ wsId == t) l1 l2) m because the message might have been sent using broadcastMessage rather than sendMessage, so we again might not be the main workspace. I'm not sure of the best fix for this. It'd be tempting to write a function to send a YouAreWorkspace message to all layouts right at the very beginning. We ought to have some sort of an "initialization hook" that could be called just once on startup. One could stick this in a key binding, but that'd be just ugly... We could also, in doLayout, examine the window stack we are given and compare it with those in all the visible workspaces to try to figure out who we are. This could have the advantage of keeping your elegant user interface (users don't need to consider what hooks they've got), but would also suffer from confusion when two workspaces having the same set of windows. It'd be relatively ugly to code, but would have the advantage of being relatively robust. I think this is what I'd do. And you could just ignore any Messages until you've figured out who you are. I don't think there are any really important messages that can come to a Layout before it's ever displayed a window. -- David Roundy Department of Physics Oregon State University

On Tue, Nov 20, 2007 at 07:01:19AM -0800, David Roundy wrote:
On Mon, Nov 19, 2007 at 09:54:06PM -0500, Brent Yorgey wrote:
As seen on xmonad@! A module which allows you to configure layouts per-workspace. Testing, comments, criticisms, edits, etc. welcome.
I'd also add that I think it'd be handy to be able to give a list of WorkspaceId rather than just one, so we could say onWorkspaces ["web","email","irc"] mytabbed $ onWorkspaces ["darcs","xmonad"] (mytabbed <-//> mytabbed ||| mytabbed) $ Full That'd be a stupid set of layouts, but you can see the idea: most users will have two or three sets of layouts, max, and will want to divy them up among their workspaces. -- David Roundy Department of Physics Oregon State University

On Nov 20, 2007 10:06 AM, David Roundy
On Tue, Nov 20, 2007 at 07:01:19AM -0800, David Roundy wrote:
On Mon, Nov 19, 2007 at 09:54:06PM -0500, Brent Yorgey wrote:
As seen on xmonad@! A module which allows you to configure layouts per-workspace. Testing, comments, criticisms, edits, etc. welcome.
I'd also add that I think it'd be handy to be able to give a list of WorkspaceId rather than just one, so we could say
onWorkspaces ["web","email","irc"] mytabbed $ onWorkspaces ["darcs","xmonad"] (mytabbed <-//> mytabbed ||| mytabbed) $ Full
That'd be a stupid set of layouts, but you can see the idea: most users will have two or three sets of layouts, max, and will want to divy them up among their workspaces.
I thought of this, but the problem is the types. What should the type of onWorkspaces be? If you try to write this function, you get an infinite type error. Unless there's some tricky type-hacking that can be done to get around it. -Brent

On Tue, Nov 20, 2007 at 11:07:50AM -0500, Brent Yorgey wrote:
I'd also add that I think it'd be handy to be able to give a list of WorkspaceId rather than just one, so we could say
onWorkspaces ["web","email","irc"] mytabbed $ onWorkspaces ["darcs","xmonad"] (mytabbed <-//> mytabbed ||| mytabbed) $ Full
That'd be a stupid set of layouts, but you can see the idea: most users will have two or three sets of layouts, max, and will want to divy them up among their workspaces.
I thought of this, but the problem is the types. What should the type of onWorkspaces be? If you try to write this function, you get an infinite type error. Unless there's some tricky type-hacking that can be done to get around it.
onWorkspaces onWorkspaces :: (LayoutClass l1 a, LayoutClass l2 a) => [WorkspaceId] -- ^ the tag of workspaces to match -> (l1 a) -- ^ layout to use on the matched workspace -> (l2 a) -- ^ layout to use everywhere else -> PerWorkspace l1 l2 a data PerWorkspace l1 l2 a = PerWorkspace [WorkspaceId] (Maybe Bool) (l1 a) (l2 a) deriving (Read, Show) I think that's the key: moving the functionality into the data type. -- David Roundy Department of Physics Oregon State University

On Nov 20, 2007 11:10 AM, David Roundy
I'd also add that I think it'd be handy to be able to give a list of WorkspaceId rather than just one, so we could say
onWorkspaces ["web","email","irc"] mytabbed $ onWorkspaces ["darcs","xmonad"] (mytabbed <-//> mytabbed ||| mytabbed) $ Full
That'd be a stupid set of layouts, but you can see the idea: most users will have two or three sets of layouts, max, and will want to divy
On Tue, Nov 20, 2007 at 11:07:50AM -0500, Brent Yorgey wrote: them up
among their workspaces.
I thought of this, but the problem is the types. What should the type of onWorkspaces be? If you try to write this function, you get an infinite type error. Unless there's some tricky type-hacking that can be done to get around it.
onWorkspaces onWorkspaces :: (LayoutClass l1 a, LayoutClass l2 a) => [WorkspaceId] -- ^ the tag of workspaces to match -> (l1 a) -- ^ layout to use on the matched workspace -> (l2 a) -- ^ layout to use everywhere else -> PerWorkspace l1 l2 a
data PerWorkspace l1 l2 a = PerWorkspace [WorkspaceId] (Maybe Bool) (l1 a) (l2 a) deriving (Read, Show)
I think that's the key: moving the functionality into the data type.
Ah, indeed! Thanks. -Brent

On Nov 20, 2007 10:01 AM, David Roundy
On Mon, Nov 19, 2007 at 09:54:06PM -0500, Brent Yorgey wrote:
As seen on xmonad@! A module which allows you to configure layouts per-workspace. Testing, comments, criticisms, edits, etc. welcome.
This is buggy when multiple screens are in use, because of the following code:
-- figure out which layout to use based on the current workspace. doLayout (PerWorkspace wsId Nothing l1 l2) r s = do t <- getCurrentTag doLayout (PerWorkspace wsId (Just $ wsId == t) l1 l2) r s
There's no guarantee that the *current* screen is the one that's having doLayout called. :(
We also have trouble with:
handleMessage (PerWorkspace wsId Nothing l1 l2) m = do t <- getCurrentTag handleMessage (PerWorkspace wsId (Just $ wsId == t) l1 l2) m
because the message might have been sent using broadcastMessage rather than sendMessage, so we again might not be the main workspace.
David, thanks for the bug reports. I don't have multiple screens so I didn't even think about that problem... oops! Unfortunately, I don't have a lot of time right now, so for the moment I think I will just change the code to ignore messages received before doLayout gets called, and add a note to say that it doesn't (yet) work in conjunction with multiple screens. If someone wants to try fixing it in a more general way, be my guest. -Brent

On Tue, Nov 20, 2007 at 11:11:57AM -0500, Brent Yorgey wrote:
David, thanks for the bug reports. I don't have multiple screens so I didn't even think about that problem... oops! Unfortunately, I don't have a lot of time right now, so for the moment I think I will just change the code to ignore messages received before doLayout gets called, and add a note to say that it doesn't (yet) work in conjunction with multiple screens. If someone wants to try fixing it in a more general way, be my guest.
Sounds good to me. I fully understand a lack of time. -- David Roundy Department of Physics Oregon State University
participants (3)
-
Brent Yorgey
-
David Roundy
-
Devin Mullins