darcs patch: Module for automatic placement of floating windows

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! Quentin

Should there be a patch attached? 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!
Quentin _______________________________________________ xmonad mailing list xmonad@haskell.org http://www.haskell.org/mailman/listinfo/xmonad

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

On Thu, 9 Apr 2009 11:42:44 +0200
Quentin Moser
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''
My example is wrong. I think this version should be correct:
instance Monoid (Query (Endo WindowSet)) where mempty = return $ Endo id mappend m1 m2 = do endo1 <- m1 ws' <- appEndo endo1 <$> getWS setWS ws'
endo2 <- m1 ws'' <- appEndo endo1 <$> getWS setWS ws''
return $ Endo $ const ws''
The point is for the Query parts and Endo Windowset parts do be interleaved and manipulate the same windowset.

* On Thursday, April 09 2009, Quentin Moser wrote:
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).
Which issues did you run into in trying to manipulate the WindowSet in placing floating windows? I think that you can avoid the call to moveWindow by updating the Data.Map.Map in the WindowSet to respect the new position. If that works, then hopefully those questionable alternatives you suggested might not be necessary. Adam
participants (3)
-
Adam Vogt
-
Don Stewart
-
Quentin Moser