
On Wed, 8 Apr 2009 10:21:36 +0200
Quentin Moser
After months of getting all my floating windows spawned in the top-left corner and moving them by hand I finally broke down and wrote a floating window module.
This module provides both a ManageHook and an X action to manually trigger repositioning of the focused window, supports both WindowArranger and "real" floating windows, and implements the usual placement policies (smart, fixed position, under the mouse).
I haven't tested it extensively yet but everything I've tried to do with it worked as intended. At any rate, comments are welcome if you think there's something wrong with it.
Hope someone finds this useful!
Sorry, seems I'd forgotten to actually attach the patch... Well, here it is. Also, I've reached a stumbling block when trying to improve my placeHook function. It currently acts on the WindowSet obtained by 'gets windowset', and simply returns 'Endo id'. The reason for this is obvious: It needs to do stateful stuff (namely get and set window positions at the X11 level), and there's no way I can fit that in a function (f :: WindowSet -> WindowSet). Because of this, placeHook can exhibit some weird behavior when combined with other hooks. For example, smart placement will always place a new window according to the positions of the windows in the current workspace, even if it has been transfered to another workspace by doShift. I can currently see two ways of solving this: - Use some unsafePerformIO ugliness in placeHook. This is bad for obvious reasons, but should still be possible. - Define a more ad-hoc Monoid instance specific to (Query (Endo WindowSet)) that interleaves the execution of the monadic parts and Endo parts. Something like this (haven't tested it):
instance Monoid (Query (Endo WindowSet)) where mempty = return $ Endo id mappend m1 m2 = do ws <- Query $ lift $ gets windowset ws' <- m1 >>= ($ ws) . appEndo ws'' <- m2 >>= ($ ws') . appEndo Query $ lift $ modify $ \s -> s {windowset = ws''} return $ Endo $ const ws''
Actually, I think the Endo idea in itself is too restrictive an interface, and ManageHook should rather be aliased to something like (WindowSet -> Query WindowSet), but this would obviously break way too much code. Thus the instance above, which provides the same kind of flexibility in a backward-compatible way. The main disadvantage of this second approach is that it requires a modifying the xmonad core, and, moreover, in a fairly ugly way (the general Monoid Query instance is much more elegant). I feel the current ManageHook interface is unnecessarily restrictive and such a modification would be justified, but this is definitely open to discussion. Any thoughts? Ideas? Should I submit a patch to XMonad.Core? Did I miss an overall better solution? Let me reiterate that my placement patch already works without problem except for a few special situations. I am only starting this discussion because I think the problem it addresses will also appear on other occasions in the future. Q