[xmonad] A proper way to make XMonad.Actions.WindowMenu configurable?

Brandon Allbery allbery.b at gmail.com
Sun Apr 5 13:39:59 UTC 2020


For what it's worth, you normally get the XConf via `ask`
(Control.Monad.Reader) instead of passing it around. The primary exception
is in ManageHooks, which have a different Reader on top and you must use
`liftX` first to get at the other one.

Your own actions would not normally be part of the XConf or XConfig, but a
separate type which you would pass around. Compare something like
XMonad.Prompt and its `XPConfig` type.

On Fri, Apr 3, 2020 at 10:46 AM Michal J. <wlst-xmonad at zruze.cz> wrote:

> Hello friendly folks,
>
> I'm a relative newb to both xmonad and Haskell, and for a while I
> wrestled with a seemingly simple task -- to make XMonad.Actions.WindowMenu
> (from xmonad-contrib) configurable.
>
> Essentially I wanted to go from:
>
> windowMenu :: X ()
> windowMenu = ...
>
> to:
>
> windowMenu :: ??? -> X ()
> windowMenu actions = ...
>
> so I can customize the actions that pop up. So I can bind different menus
> to different key combos.
>
> Now, I documented some of my struggles at Stack Overflow:
> https://stackoverflow.com/q/61001342/1177128
> and eventually came up with a solution (with help from others!):
> https://stackoverflow.com/a/61013887/1177128
>
> But given that grepping the xmonad and xmonad-contrib sources for
> ":: XConf ->" returns exactly 1 result (spoiler: `runX` in `Core.hs`), I'm
> pretty sure I'm holding it wrong:
>
> ```haskell
> defaultActions :: XConf -> [(String, X ())]
> defaultActions = do
>     tags <- asks (workspaces . config)
>     return ([ ("Cancel menu", return ())
>             , ("Close"      , kill)
>             , ("Maximize"   , withFocused $ \w -> sendMessage $
> maximizeRestore w)
>             , ("Minimize"   , withFocused $ \w -> minimizeWindow w)
>             ] ++
>             [ ("Move to " ++ tag, windows $ W.shift tag) | tag <- tags ])
>
> windowMenu' :: (XConf -> [(String, X ())]) -> X ()
> windowMenu' actions = withFocused $ \w -> do
>     acts <- asks actions
>     Rectangle x y wh ht <- getSize w
>     Rectangle sx sy swh sht <- gets $ screenRect . W.screenDetail .
> W.current . windowset
>     let originFractX = (fi x - fi sx + fi wh / 2) / fi swh
>         originFractY = (fi y - fi sy + fi ht / 2) / fi sht
>         gsConfig = (buildDefaultGSConfig colorizer)
>                     { gs_originFractX = originFractX
>                     , gs_originFractY = originFractY }
>     runSelectedAction gsConfig acts
>
> -- now it composes well, and I can pass in my own `actions` to `windowMenu`
> windowMenu = windowMenu' defaultActions
> ```
>
> Can anyone well versed in the idiosyncrasies of Haskell and XMonad please
> point out what would be the proper -- nay, canonical -- solution if it were
> done by someone who actually knows what they're doing?
>
> It'd be greatly appreciated. :-)
>
> Cheers,
>
> Michal
>
> PS: If the refactor seems like I really have no clue what's going on...
>     well... I don't. And if you have a pointer to some text I should
>         read to understand all this better, I'm all ears.
> _______________________________________________
> xmonad mailing list
> xmonad at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad
>


-- 
brandon s allbery kf8nh
allbery.b at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/xmonad/attachments/20200405/f554ee22/attachment.html>


More information about the xmonad mailing list