[draft] workspace layouts
Description
This PR introduces "workspace layouts", which allow non-standard organization of the workspaces themselves, such as alignment into a grid, or combination of multiple workspaces.
The modules (at the time of PR creation) are as follows:
-
XMonad.Util.OneStateandXMonad.WorkspaceLayout.Util-- Utility modules -
XMonad.WorkspaceLayout.Core-- Defines functionality shared between workspace layouts -
XMonad.WorkspaceLayout.Grid-- Defines a 2d-grid workspace layout. This is likeXMonad.Actions.Plane, but not hacky and more featurful. The grid layout allows the user to organize their workspaces into a grid and for multiple coordinates on the grid to map to the same workspace. -
XMonad.WorkspaceLayout.Cycle-- Defines a cyclic workspace layout. This module is intended to be more of a demonstration than anything. Its use for me during development was to help mitigate the risk of me over-coupling generic code with the grid layout.
Let me elaborate a bit on the deal with the grid layout by way of giving the example of my own current XMonad layout. I have a grid which is 10 cells across, and 4 cells tall. Altogether it looks like this:
y=1 | α 1 2 3 4 γ 6 7 8
y=2 | α 1 2 3 4 γ 6 7 8
y=3 | α 1 2 3 4 γ 6 7 8
y=4 | α 1 2 3 4 γ 6 7 8
This means that I have a grid of 32 cells total. Each row has the same names for its cells but these cells are distinct.
As I write this, I am positioned on cell α of row y=1:

Using keybindings MOD+n for a number n, I can move around the row y=1 to other workspaces on that row. If I press MOD+3, for instance, I move to workspace 3 on row y=1, which contains some terminals:

To move around the y-axis, I press MOD+s to increment y and MOD+w to decrement it. If I increment y twice to reach row y=3, my status bar looks like this:

This row contains a different set of workspaces than y=1, hence the difference in coloration for the labels.
It's also worth noting that I have the α and γ cells in each row to be linked together. This means that if I am on row y=2 and open a terminal in cell γ, and then I move to cell γ of row y=3, the same terminal will be there. Under the hood, the workspaces y=2 γ and y=3 γ are actually the same workspace.
My intent with the inclusion of the namespace XMonad.WorkspaceLayout and the module XMonad.WorkspaceLayout.Core is to encourage other XMonad contributors to possibly create and add their own workspace layouts besides just Grid and Cycle. (As it so happens, XMonad.WorkspaceLayout.Core turned out to be minimal in terms of code, but so be it.)
This PR is far from complete. The checklist below enumerates a number of outstanding tasks.
However, I wanted to open it earlier rather than later to start receiving feedback as soon as possible. Some questions include:
- Is there interest for the grid and cycle layouts?
- Is there interest for the generic "workspace layout" abstraction and the
XMonad.WorkspaceLayoutnamespace? - Should the "workspace layout" abstraction be developed, so that the
XMonad.WorkspaceLayout.Coreaffordance is not so ... lacking?
Thanks!
post-script. I recognize that I haven't include any example client code that uses this PR. As of right now, the best example I have is my own XMonad config; see specifically how I hook into XMonad, hook into my status bar, and deifne my keybindings.
Checklist
- [x] Read CONTRIBUTING.md
- [ ] Documentation: comments + examples
- [ ] Manual tests performed
- [ ]
xmonad-contribtests still pass - [ ]
CHANGES.mdupdated - [ ]
hlintpasses - [ ] PR generates no new warnings
Just chiming in to say that this looks really cool! I don't have the capacity to review this in full just now, but it's definitely on my radar!
And I think the
WorkspaceLayout.*shouldn't be a top-level submodule ofXMonad.XMonad.Utilmight be a good fit.
Don't want to bikeshed too much but can't resist here: this WorkspaceLayout stuff is closer to XMonad.Layout.IndependentScreens than to anything in XMonad.Util. Arguably IndependentScreens is not a window layout, it's more of a … workspace layout. If none of this already existed I'd probably put it in XMonad.Actions because all this workspace layout logic mostly happens in keybindings that switch workspaces, but that's just me trying to fit this into the existing namespace.
Anyway, that's just my thoughts. Not a suggestion, not a conclusion, just a thought experiment. :-)
@Quelklef Hi, I tried few days ago KDE "activities" feature first time, and I want to share some ideas with you.
What activity-like features I would like to have:
- different workspace list per activity. Similar to
XMonad.Actions.TreeSelect, workspace name can be separated via ".", so no need 2 dimensions (name like "Work.Proj1.Term" is also allowed - activity name will be "Work.Proj1") e.g:
[ "Relax.WWW" "Relax.DOC", "Relax.Gimp"
,"Work.Term", "Work.WWW" "Work.Editor", "Work.etc"
,"MyProjects.Term", "MyProjects.WWW" "MyProjects.Editor", "MyProjects.etc"
,"Study.WWW", "Study.Doc", "Study.Doc" ]
- Hook when switching between activities (e.g changing from "Relax" to "Work"). I can have different statusbars with different widgets. I think it possible to hide/show them depending on workspace activity prefix name (spawn xdotool, wmctl?). I can change background when workspace's activity is changed.
- When switching "activity" (move Y) return to last active workspace.
- Some label/indicator in statusbar when I have windows not in current activity, or/and count of windows not in current activity.
Again, this is just ideas and not request for change and might be done in another module but it is very close to your module and you might want to have smtg from above list for yourself needs
Hi @osv, thank you for the comment! Let me make sure I am understanding you correctly. You're thinking of using the y-axis in order to keep track of what "activity" you are engaging with. And you are thinking that:
- On different activities, workspaces can have different names. So in the Relax acitivity workspaces would be WWW, DOC, Gimp but in Work workspaces would Term, WWW, Editor, etc.
- There would be a hook for detecting a change of activity
- When switching activities the previously-active workspace would be automatically active
- There would be some kind of indication regarding how many active windows there are not shown in the current activity
These are some interesting suggestions. Here are my thoughts --
- You can already do this with the current
WorkspaceLayoutimplementation. In my examples, workspaces are named after their x-coordinate, but in actuality you can name them whatever you want :P - The
WorkspaceLayoutimplementation on its own does not control when workspaces are changed; the user does. The user has to configure, for instance, that Super+W moves the y-coordinate down by one. If the user also wants something to happen on workspace change, they can add that code to the callsite. In other words, they can change the (hypothetical) callsiteon "Super+W" (changeCoordinate addOneToY)toon "Super+W" (changeCoordinate addOneToY >> doSomethingElse) - I think the user could technically add this themselves, but it seems like a reasonable thing to have built-in
- A user should be able to configure this themselves using
neighborhoodandlabelfromWorkspaceLayoutView. That being said, it might also be a good addition toWorkspaceLayoutproper, assuming it doesn't require too much code to implement
I probably won't implement these right now, since it's unclear to me whether or not this PR is headed towards merging or not anyway. If it is eventually merged (or it is known that it will eventually be merged), I'd be happy to look more into implementing these =)
- Yes, different count of activities namespaces (all what is need for it, as I understand, just new ppRename function to hide namespaces not in current activity)
- I would like to have hook when activity is changed, it will be more integrated solution with other modules I think (new separate hook needed).
- This is more question where to go when you are moving in Y. First workspace in list? Probably in most cases user would like return back to the last one used so need to keep state of last visited activiries (one more hook)
- Yes, it possible to do with module in this PR. This draft have no example in doc (this is draft, so it is ok maybe) how to use, so I need to check your dotfiles, but better add synopsis/example of usage in modules directly)