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

Michal J. wlst-xmonad at zruze.cz
Fri Apr 3 14:45:35 UTC 2020


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.


More information about the xmonad mailing list