Agaginst LayoutModifiers for hooks

Hi, 0.4 is out, and I’m bringing up my old issue: Hooks. I quote the docs for the recent UrgencyHook extension:
Change your defaultLayout such that withUrgencyHook is applied along the chain. Mine, for example:
defaultLayout = Layout $ withUrgencyHook $ windowNavigation wnConfig $ LayoutSelection defaultLayouts
It shouldn't hurt to have the "withUrgencyHook $" at the outermost layer, as above, as UrgencyHook is a LayoutModifier, and hence passes on any messages sent to it.
Is this really what we want our users to go through just so that they can add a simple extension? And what do urgency hooks have to do with Layouts? Wouldn’t this be much nicer:
Add urgencyHook to your xmonadHook list:
xmonadHooks = [ urgencyHook , otherHooksYouAlreadyHave ]
I will, in this post, leave out any discussion on how to implement this. Instead, I’d like to talk about the _user interface_ of adding extensions. Do you think we should make adding extensions easier for the user? How should registering extensions work in the configuration file? My suggestion is that there should be just one list, xmonadHooks (or xmonadExtensions, to further hide details from the user), where extensions are added. Options are just passed along, so for example:
-- User option for the UrgencyHook extension:
urgencyAction window = do print "Something is urgent"
xmonadHooks = [ urgencyHook urgencyAction , otherHooksYouAlreadyHave ]
Any comments on that? Greetings, Joachim -- Joachim Breitner e-Mail: mail@joachim-breitner.de Homepage: http://www.joachim-breitner.de ICQ#: 74513189

On Thu, Oct 18, 2007 at 04:02:49PM +0200, Joachim Breitner wrote:
Hi,
Hello.
0.4 is out, and I'm bringing up my old issue: Hooks.
I quote the docs for the recent UrgencyHook extension:
Change your defaultLayout such that withUrgencyHook is applied along the chain. Mine, for example:
defaultLayout = Layout $ withUrgencyHook $ windowNavigation wnConfig $ LayoutSelection defaultLayouts
It shouldn't hurt to have the "withUrgencyHook $" at the outermost layer, as above, as UrgencyHook is a LayoutModifier, and hence passes on any messages sent to it.
Is this really what we want our users to go through just so that they can add a simple extension? And what do urgency hooks have to do with Layouts? Wouldn't this be much nicer:
I don't see that a list of extensions one place is much harder on our users than a list of extensions some other place.
Add urgencyHook to your xmonadHook list:
xmonadHooks = [ urgencyHook , otherHooksYouAlreadyHave ]
I will, in this post, leave out any discussion on how to implement this. Instead, I'd like to talk about the _user interface_ of adding extensions.
Note that you've immediately restricted the expressive power, by choosing a list (and I presume, choosing that the order of items in the list doesn't matter?). Of course, limiting what we can do can help keep users from shooting themselves in the foot, but it's also not necesarily the best starting point.
Do you think we should make adding extensions easier for the user? How should registering extensions work in the configuration file?
I don't think adding (Foo $) to one part of the file is much harder than adding (Foo,) to another part of the file.
My suggestion is that there should be just one list, xmonadHooks (or xmonadExtensions, to further hide details from the user), where extensions are added. Options are just passed along, so for example:
-- User option for the UrgencyHook extension:
urgencyAction window = do print "Something is urgent"
xmonadHooks = [ urgencyHook urgencyAction , otherHooksYouAlreadyHave ]
Any comments on that?
This definitely could be nice, but I'm not sure that it's sufficiently powerful, and would prefer it to be a contrib API to start out with (as I've said more times that either of us want to count). -- David Roundy Department of Physics Oregon State University

Hi, Am Donnerstag, den 18.10.2007, 10:20 -0400 schrieb David Roundy:
On Thu, Oct 18, 2007 at 04:02:49PM +0200, Joachim Breitner wrote:
0.4 is out, and I'm bringing up my old issue: Hooks.
I quote the docs for the recent UrgencyHook extension:
Change your defaultLayout such that withUrgencyHook is applied along the chain. Mine, for example:
defaultLayout = Layout $ withUrgencyHook $ windowNavigation wnConfig $ LayoutSelection defaultLayouts
It shouldn't hurt to have the "withUrgencyHook $" at the outermost layer, as above, as UrgencyHook is a LayoutModifier, and hence passes on any messages sent to it.
Is this really what we want our users to go through just so that they can add a simple extension? And what do urgency hooks have to do with Layouts? Wouldn't this be much nicer:
I don't see that a list of extensions one place is much harder on our users than a list of extensions some other place.
Well, the one thing is a list of extensions, so it is clear what I have to do: List the extensions I want. The other thing is how I cascade my Layouts, and it is everything but obvious how an UrgencyHook modifies my layout.
Note that you've immediately restricted the expressive power, by choosing a list (and I presume, choosing that the order of items in the list doesn't matter?). Of course, limiting what we can do can help keep users from shooting themselves in the foot, but it's also not necesarily the best starting point.
I’ve only limited it for the first registering of extensions functionality, and with a reason: Any power needed above this can be put in an Extension itself (which would actually reduce code in the core). The canonical example seems to be matching on window names when managing a window, where you currently have a function with lots of parameters. I’d propose to put that functionality in an extension (just like there is already one for matching XProperties), and let that extension be configured in whatever way seems to be most suitable. For example:
-- Registering the extensions, naming the options: xmonadHooks = [ windowNameExtension nameMatch ,.... ]
-- Setting the optins: nameMatch :: Window -> String -> String -> X () -- or whatever nameMatch w "firefox" _ _ = do ...
Do you think we should make adding extensions easier for the user? How should registering extensions work in the configuration file?
I don't think adding (Foo $) to one part of the file is much harder than adding (Foo,) to another part of the file.
Don’t think it makes a difference that one part of the file might be explicitly created to register extensions, while the other part was intended to manage layouts and is just abused to catch messages?
My suggestion is that there should be just one list, xmonadHooks (or xmonadExtensions, to further hide details from the user), where extensions are added. Options are just passed along, so for example:
-- User option for the UrgencyHook extension:
urgencyAction window = do print "Something is urgent"
xmonadHooks = [ urgencyHook urgencyAction , otherHooksYouAlreadyHave ]
Any comments on that?
This definitely could be nice, but I'm not sure that it's sufficiently powerful, and would prefer it to be a contrib API to start out with (as I've said more times that either of us want to count).
Right, and I promised to work on that after the release of 0.4 − that is, now. But I think you agree that having this in a contrib module can just be a proof-of-concept and not the real thing, as the goal is to simplify configuration, and at least for this „proxy module“, the user would still have to fiddle with the various ways of adding hooks manually. I’m also a bit surprised that no one else seems to have an opinion on this. Greetings, Joachim -- Joachim Breitner e-Mail: mail@joachim-breitner.de Homepage: http://www.joachim-breitner.de ICQ#: 74513189

On Thu, Oct 18, 2007 at 04:30:42PM +0200, Joachim Breitner wrote:
This definitely could be nice, but I'm not sure that it's sufficiently powerful, and would prefer it to be a contrib API to start out with (as I've said more times that either of us want to count).
Right, and I promised to work on that after the release of 0.4 − that is, now. But I think you agree that having this in a contrib module can just be a proof-of-concept and not the real thing, as the goal is to simplify configuration, and at least for this „proxy module“, the user would still have to fiddle with the various ways of adding hooks manually.
I agree that that would be the goal, as it was also the goal of LayoutSelection (which is now in core). However, this module shouldn't be hard to use as a contrib, either.
I'm also a bit surprised that no one else seems to have an opinion on this.
Me too. :) -- David Roundy Department of Physics Oregon State University

On Thu, Oct 18, 2007 at 04:30:42PM +0200, Joachim Breitner wrote:
I’m also a bit surprised that no one else seems to have an opinion on this.
I do have an opinion on the subject, but still I don't understand what your aim is, actually. At first we started talking about a set of hooks, and a way of managing them, but now it seems to me you were proposing a different way of managing hooks *and* extensions. As David noted, I don't know if a list of extensions is really expressive enough - or, on the other side, if it is creating strong requirements on the basic functionality an extension *must* provide to be 'listable' and thus usable... if I get this part of the problem right. For the general issue of having some kind of hook management, to be used instead of LayoutModifiers, I agree with you: there are operations our users may be willing to add to (or to remove from) xmonad that should not be carried out at the layout level (XEvents and logging being the main examples that come to my mind). Proper support in the core should be provided in my opinion. I totally agree with David that starting with a contrib module should be the preferred path, though. Andrea

On Thu, Oct 18, 2007 at 05:06:41PM +0200, Andrea Rossato wrote:
I do have an opinion on the subject... <snip opinion>
What Andrea said. I was thinking about some of the annoying hacks I had to do for UrgencyHook, and being able to configure a list of hooks that could be wired to listen on any event(s) would make the requirement for a new top level binding in Config.hs go away, and hence not require the user to mess with Config.hs-boot. Devin

On Thu, Oct 18, 2007 at 10:51:35PM -0400, Devin Mullins wrote:
On Thu, Oct 18, 2007 at 05:06:41PM +0200, Andrea Rossato wrote:
I do have an opinion on the subject... <snip opinion>
What Andrea said. I was thinking about some of the annoying hacks I had to do for UrgencyHook, and being able to configure a list of hooks that could be wired to listen on any event(s) would make the requirement for a new top level binding in Config.hs go away, and hence not require the user to mess with Config.hs-boot.
This, however, is orthogonal to Joachim's proposal. His proposal could reduce the pain for users of adding more hooks, but wouldn't reduce the danger of an over-complex API, which I think is our primary concern. But I agree, event hooks should go in. The question is in what form. e.g. we may find that reasonable uses of event hooks require the ability to store state, as layouts do. It'd be a shame to add a hook in a form that required non-trivial event-hooks to be implemented as layout modifiers after all. e.g. what if we want a hook that binds a key an event to focus the most-recently-urgent window. This is reasonably easily implemented as a layout modifier, but would require the use of unsafePerformIO to construct a global variable when implemented with Joachim's proposed hooks. Or perhaps using the X server to store the global variable (as the tags extension does)... but I'm not convinced that the X server is the best location for global variables. Maybe it is. -- David Roundy Department of Physics Oregon State University
participants (4)
-
Andrea Rossato
-
David Roundy
-
Devin Mullins
-
Joachim Breitner